@langchain/langgraph-sdk 0.0.111 → 0.0.112

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @langchain/langgraph-sdk
2
2
 
3
+ ## 0.0.112
4
+
5
+ ### Patch Changes
6
+
7
+ - a50e02e: feat(sdk): add thread streaming endpoint
8
+ - 7e210a1: feat(sdk): add durability param to run methods
9
+ - 5766b62: Fix `isThreadLoading: false` when initially mounting in useStream
10
+
3
11
  ## 0.0.111
4
12
 
5
13
  ### Patch Changes
package/dist/client.cjs CHANGED
@@ -244,6 +244,7 @@ class CronsClient extends BaseClient {
244
244
  multitask_strategy: payload?.multitaskStrategy,
245
245
  if_not_exists: payload?.ifNotExists,
246
246
  checkpoint_during: payload?.checkpointDuring,
247
+ durability: payload?.durability,
247
248
  };
248
249
  return this.fetch(`/threads/${threadId}/runs/crons`, {
249
250
  method: "POST",
@@ -270,6 +271,7 @@ class CronsClient extends BaseClient {
270
271
  multitask_strategy: payload?.multitaskStrategy,
271
272
  if_not_exists: payload?.ifNotExists,
272
273
  checkpoint_during: payload?.checkpointDuring,
274
+ durability: payload?.durability,
273
275
  };
274
276
  return this.fetch(`/runs/crons`, {
275
277
  method: "POST",
@@ -666,6 +668,24 @@ class ThreadsClient extends BaseClient {
666
668
  },
667
669
  });
668
670
  }
671
+ async *joinStream(threadId, options
672
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
673
+ ) {
674
+ const response = await this.asyncCaller.fetch(...this.prepareFetchOptions(`/threads/${threadId}/stream`, {
675
+ method: "GET",
676
+ headers: options?.lastEventId
677
+ ? { "Last-Event-ID": options.lastEventId }
678
+ : undefined,
679
+ params: options?.streamMode
680
+ ? { stream_mode: options.streamMode }
681
+ : undefined,
682
+ }));
683
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
684
+ const stream = (response.body || new ReadableStream({ start: (ctrl) => ctrl.close() }))
685
+ .pipeThrough((0, sse_js_1.BytesLineDecoder)())
686
+ .pipeThrough((0, sse_js_1.SSEDecoder)());
687
+ yield* stream_js_1.IterableReadableStream.fromReadableStream(stream);
688
+ }
669
689
  }
670
690
  exports.ThreadsClient = ThreadsClient;
671
691
  class RunsClient extends BaseClient {
@@ -699,6 +719,7 @@ class RunsClient extends BaseClient {
699
719
  after_seconds: payload?.afterSeconds,
700
720
  if_not_exists: payload?.ifNotExists,
701
721
  checkpoint_during: payload?.checkpointDuring,
722
+ durability: payload?.durability,
702
723
  };
703
724
  const endpoint = threadId == null ? `/runs/stream` : `/threads/${threadId}/runs/stream`;
704
725
  const response = await this.asyncCaller.fetch(...this.prepareFetchOptions(endpoint, {
@@ -744,6 +765,7 @@ class RunsClient extends BaseClient {
744
765
  after_seconds: payload?.afterSeconds,
745
766
  if_not_exists: payload?.ifNotExists,
746
767
  checkpoint_during: payload?.checkpointDuring,
768
+ durability: payload?.durability,
747
769
  langsmith_tracer: payload?._langsmithTracer
748
770
  ? {
749
771
  project_name: payload?._langsmithTracer?.projectName,
@@ -806,6 +828,7 @@ class RunsClient extends BaseClient {
806
828
  after_seconds: payload?.afterSeconds,
807
829
  if_not_exists: payload?.ifNotExists,
808
830
  checkpoint_during: payload?.checkpointDuring,
831
+ durability: payload?.durability,
809
832
  langsmith_tracer: payload?._langsmithTracer
810
833
  ? {
811
834
  project_name: payload?._langsmithTracer?.projectName,
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Assistant, AssistantGraph, AssistantSortBy, AssistantSelectField, AssistantVersion, CancelAction, Checkpoint, Config, Cron, CronSelectField, CronCreateForThreadResponse, CronCreateResponse, CronSortBy, DefaultValues, GraphSchema, Item, ListNamespaceResponse, Metadata, Run, RunSelectField, RunStatus, SearchItemsResponse, SortOrder, Subgraphs, Thread, ThreadSelectField, ThreadSortBy, ThreadState, ThreadStatus } from "./schema.js";
2
2
  import type { Command, CronsCreatePayload, OnConflictBehavior, RunsCreatePayload, RunsStreamPayload, RunsWaitPayload, StreamEvent } from "./types.js";
3
- import type { StreamMode, TypedAsyncGenerator } from "./types.stream.js";
3
+ import type { StreamMode, ThreadStreamMode, TypedAsyncGenerator } from "./types.stream.js";
4
4
  import { AsyncCaller, AsyncCallerParams } from "./utils/async_caller.js";
5
5
  type HeaderValue = string | undefined | null;
6
6
  /**
@@ -375,6 +375,14 @@ export declare class ThreadsClient<TStateType = DefaultValues, TUpdateType = TSt
375
375
  checkpoint?: Partial<Omit<Checkpoint, "thread_id">>;
376
376
  metadata?: Metadata;
377
377
  }): Promise<ThreadState<ValuesType>[]>;
378
+ joinStream(threadId: string, options?: {
379
+ lastEventId?: string;
380
+ streamMode?: ThreadStreamMode | ThreadStreamMode[];
381
+ }): AsyncGenerator<{
382
+ id?: string;
383
+ event: StreamEvent;
384
+ data: any;
385
+ }>;
378
386
  }
379
387
  export declare class RunsClient<TStateType = DefaultValues, TUpdateType = TStateType, TCustomEventType = unknown> extends BaseClient {
380
388
  stream<TStreamMode extends StreamMode | StreamMode[] = StreamMode, TSubgraphs extends boolean = false>(threadId: null, assistantId: string, payload?: Omit<RunsStreamPayload<TStreamMode, TSubgraphs>, "multitaskStrategy" | "onCompletion">): TypedAsyncGenerator<TStreamMode, TSubgraphs, TStateType, TUpdateType, TCustomEventType>;
package/dist/client.js CHANGED
@@ -239,6 +239,7 @@ export class CronsClient extends BaseClient {
239
239
  multitask_strategy: payload?.multitaskStrategy,
240
240
  if_not_exists: payload?.ifNotExists,
241
241
  checkpoint_during: payload?.checkpointDuring,
242
+ durability: payload?.durability,
242
243
  };
243
244
  return this.fetch(`/threads/${threadId}/runs/crons`, {
244
245
  method: "POST",
@@ -265,6 +266,7 @@ export class CronsClient extends BaseClient {
265
266
  multitask_strategy: payload?.multitaskStrategy,
266
267
  if_not_exists: payload?.ifNotExists,
267
268
  checkpoint_during: payload?.checkpointDuring,
269
+ durability: payload?.durability,
268
270
  };
269
271
  return this.fetch(`/runs/crons`, {
270
272
  method: "POST",
@@ -659,6 +661,24 @@ export class ThreadsClient extends BaseClient {
659
661
  },
660
662
  });
661
663
  }
664
+ async *joinStream(threadId, options
665
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
666
+ ) {
667
+ const response = await this.asyncCaller.fetch(...this.prepareFetchOptions(`/threads/${threadId}/stream`, {
668
+ method: "GET",
669
+ headers: options?.lastEventId
670
+ ? { "Last-Event-ID": options.lastEventId }
671
+ : undefined,
672
+ params: options?.streamMode
673
+ ? { stream_mode: options.streamMode }
674
+ : undefined,
675
+ }));
676
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
677
+ const stream = (response.body || new ReadableStream({ start: (ctrl) => ctrl.close() }))
678
+ .pipeThrough(BytesLineDecoder())
679
+ .pipeThrough(SSEDecoder());
680
+ yield* IterableReadableStream.fromReadableStream(stream);
681
+ }
662
682
  }
663
683
  export class RunsClient extends BaseClient {
664
684
  /**
@@ -691,6 +711,7 @@ export class RunsClient extends BaseClient {
691
711
  after_seconds: payload?.afterSeconds,
692
712
  if_not_exists: payload?.ifNotExists,
693
713
  checkpoint_during: payload?.checkpointDuring,
714
+ durability: payload?.durability,
694
715
  };
695
716
  const endpoint = threadId == null ? `/runs/stream` : `/threads/${threadId}/runs/stream`;
696
717
  const response = await this.asyncCaller.fetch(...this.prepareFetchOptions(endpoint, {
@@ -736,6 +757,7 @@ export class RunsClient extends BaseClient {
736
757
  after_seconds: payload?.afterSeconds,
737
758
  if_not_exists: payload?.ifNotExists,
738
759
  checkpoint_during: payload?.checkpointDuring,
760
+ durability: payload?.durability,
739
761
  langsmith_tracer: payload?._langsmithTracer
740
762
  ? {
741
763
  project_name: payload?._langsmithTracer?.projectName,
@@ -798,6 +820,7 @@ export class RunsClient extends BaseClient {
798
820
  after_seconds: payload?.afterSeconds,
799
821
  if_not_exists: payload?.ifNotExists,
800
822
  checkpoint_during: payload?.checkpointDuring,
823
+ durability: payload?.durability,
801
824
  langsmith_tracer: payload?._langsmithTracer
802
825
  ? {
803
826
  project_name: payload?._langsmithTracer?.projectName,
@@ -202,7 +202,11 @@ function fetchHistory(client, threadId, options) {
202
202
  }
203
203
  function useThreadHistory(threadId, client, limit, clearCallbackRef, submittingRef, onErrorRef) {
204
204
  const [history, setHistory] = (0, react_1.useState)(undefined);
205
- const [isLoading, setIsLoading] = (0, react_1.useState)(false);
205
+ const [isLoading, setIsLoading] = (0, react_1.useState)(() => {
206
+ if (threadId == null)
207
+ return false;
208
+ return true;
209
+ });
206
210
  const [error, setError] = (0, react_1.useState)(undefined);
207
211
  const clientHash = (0, client_js_1.getClientConfigHash)(client);
208
212
  const clientRef = (0, react_1.useRef)(client);
@@ -236,7 +240,7 @@ function useThreadHistory(threadId, client, limit, clearCallbackRef, submittingR
236
240
  if (submittingRef.current)
237
241
  return;
238
242
  void fetcher(threadId);
239
- }, [fetcher, clientHash, limit, submittingRef, threadId]);
243
+ }, [fetcher, submittingRef, clientHash, limit, threadId]);
240
244
  return {
241
245
  data: history,
242
246
  isLoading,
@@ -619,6 +623,7 @@ function useStream(options) {
619
623
  streamMode,
620
624
  streamSubgraphs: submitOptions?.streamSubgraphs,
621
625
  streamResumable,
626
+ durability: submitOptions?.durability,
622
627
  onRunCreated(params) {
623
628
  callbackMeta = {
624
629
  run_id: params.run_id,
@@ -1,5 +1,5 @@
1
1
  import { Client, type ClientConfig } from "../client.js";
2
- import type { Command, DisconnectMode, MultitaskStrategy, OnCompletionBehavior } from "../types.js";
2
+ import type { Command, DisconnectMode, Durability, 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
5
  import type { CheckpointsStreamEvent, CustomStreamEvent, DebugStreamEvent, EventsStreamEvent, MetadataStreamEvent, StreamMode, TasksStreamEvent, UpdatesStreamEvent } from "../types.stream.js";
@@ -304,6 +304,14 @@ interface SubmitOptions<StateType extends Record<string, unknown> = Record<strin
304
304
  */
305
305
  streamSubgraphs?: boolean;
306
306
  streamResumable?: boolean;
307
+ /**
308
+ * Whether to checkpoint during the run (or only at the end/interruption).
309
+ * - `"async"`: Save checkpoint asynchronously while the next step executes (default).
310
+ * - `"sync"`: Save checkpoint synchronously before the next step starts.
311
+ * - `"exit"`: Save checkpoint only when the graph exits.
312
+ * @default "async"
313
+ */
314
+ durability?: Durability;
307
315
  /**
308
316
  * The ID to use when creating a new thread. When provided, this ID will be used
309
317
  * for thread creation when threadId is `null` or `undefined`.
@@ -198,7 +198,11 @@ function fetchHistory(client, threadId, options) {
198
198
  }
199
199
  function useThreadHistory(threadId, client, limit, clearCallbackRef, submittingRef, onErrorRef) {
200
200
  const [history, setHistory] = useState(undefined);
201
- const [isLoading, setIsLoading] = useState(false);
201
+ const [isLoading, setIsLoading] = useState(() => {
202
+ if (threadId == null)
203
+ return false;
204
+ return true;
205
+ });
202
206
  const [error, setError] = useState(undefined);
203
207
  const clientHash = getClientConfigHash(client);
204
208
  const clientRef = useRef(client);
@@ -232,7 +236,7 @@ function useThreadHistory(threadId, client, limit, clearCallbackRef, submittingR
232
236
  if (submittingRef.current)
233
237
  return;
234
238
  void fetcher(threadId);
235
- }, [fetcher, clientHash, limit, submittingRef, threadId]);
239
+ }, [fetcher, submittingRef, clientHash, limit, threadId]);
236
240
  return {
237
241
  data: history,
238
242
  isLoading,
@@ -615,6 +619,7 @@ export function useStream(options) {
615
619
  streamMode,
616
620
  streamSubgraphs: submitOptions?.streamSubgraphs,
617
621
  streamResumable,
622
+ durability: submitOptions?.durability,
618
623
  onRunCreated(params) {
619
624
  callbackMeta = {
620
625
  run_id: params.run_id,
package/dist/types.d.ts CHANGED
@@ -5,6 +5,7 @@ export type MultitaskStrategy = "reject" | "interrupt" | "rollback" | "enqueue";
5
5
  export type OnConflictBehavior = "raise" | "do_nothing";
6
6
  export type OnCompletionBehavior = "complete" | "continue";
7
7
  export type DisconnectMode = "cancel" | "continue";
8
+ export type Durability = "exit" | "async" | "sync";
8
9
  export type StreamEvent = "events" | "metadata" | "debug" | "updates" | "values" | "messages/partial" | "messages/metadata" | "messages/complete" | "messages" | (string & {});
9
10
  export interface Send {
10
11
  node: string;
@@ -54,8 +55,17 @@ export interface RunsInvokePayload {
54
55
  checkpoint?: Omit<Checkpoint, "thread_id">;
55
56
  /**
56
57
  * Whether to checkpoint during the run (or only at the end/interruption).
58
+ * @deprecated Use `durability` instead.
57
59
  */
58
60
  checkpointDuring?: boolean;
61
+ /**
62
+ * Whether to checkpoint during the run (or only at the end/interruption).
63
+ * - `"async"`: Save checkpoint asynchronously while the next step executes (default).
64
+ * - `"sync"`: Save checkpoint synchronously before the next step starts.
65
+ * - `"exit"`: Save checkpoint only when the graph exits.
66
+ * @default "async"
67
+ */
68
+ durability?: Durability;
59
69
  /**
60
70
  * Interrupt execution before entering these nodes.
61
71
  */
@@ -12,6 +12,7 @@ import type { SubgraphCheckpointsStreamEvent } from "./types.stream.subgraph.js"
12
12
  * - "custom": Stream custom events.
13
13
  */
14
14
  export type StreamMode = "values" | "messages" | "updates" | "events" | "debug" | "tasks" | "checkpoints" | "custom" | "messages-tuple";
15
+ export type ThreadStreamMode = "run_modes" | "lifecycle" | "state_update";
15
16
  type MessageTupleMetadata = {
16
17
  tags: string[];
17
18
  [key: string]: unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-sdk",
3
- "version": "0.0.111",
3
+ "version": "0.0.112",
4
4
  "description": "Client library for interacting with the LangGraph API",
5
5
  "type": "module",
6
6
  "scripts": {