@langchain/langgraph-sdk 0.0.105 → 0.0.107

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,18 @@
1
1
  # @langchain/langgraph-sdk
2
2
 
3
+ ## 0.0.107
4
+
5
+ ### Patch Changes
6
+
7
+ - 72386a4: feat(sdk): expose stream metadata from messages via `getMessagesMetadata`
8
+ - 3ee5c20: fix(sdk): avoid setting `messages-tuple` if only `getMessagesMetadata` is requested.
9
+
10
+ ## 0.0.106
11
+
12
+ ### Patch Changes
13
+
14
+ - feat(sdk): allow setting `checkpoint: null` when submitting a run via useStream
15
+
3
16
  ## 0.0.105
4
17
 
5
18
  ### Patch Changes
@@ -34,7 +34,7 @@ class MessageTupleManager {
34
34
  });
35
35
  this.chunks = {};
36
36
  }
37
- add(serialized) {
37
+ add(serialized, metadata) {
38
38
  // TODO: this is sometimes sent from the API
39
39
  // figure out how to prevent this or move this to LC.js
40
40
  if (serialized.type.endsWith("MessageChunk")) {
@@ -51,6 +51,7 @@ class MessageTupleManager {
51
51
  return null;
52
52
  }
53
53
  this.chunks[id] ??= {};
54
+ this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;
54
55
  if (chunk) {
55
56
  const prev = this.chunks[id].chunk;
56
57
  this.chunks[id].chunk =
@@ -67,7 +68,8 @@ class MessageTupleManager {
67
68
  get(id, defaultIndex) {
68
69
  if (this.chunks[id] == null)
69
70
  return null;
70
- this.chunks[id].index ??= defaultIndex;
71
+ if (defaultIndex != null)
72
+ this.chunks[id].index ??= defaultIndex;
71
73
  return this.chunks[id];
72
74
  }
73
75
  }
@@ -396,6 +398,9 @@ function useStream(options) {
396
398
  const alreadyShown = new Set();
397
399
  return getMessages(historyValues).map((message, idx) => {
398
400
  const messageId = message.id ?? idx;
401
+ const streamMetadata = message.id != null
402
+ ? messageManagerRef.current.get(message.id)?.metadata ?? undefined
403
+ : undefined;
399
404
  const firstSeenIdx = findLastIndex(history.data ?? [], (state) => getMessages(state.values)
400
405
  .map((m, idx) => m.id ?? idx)
401
406
  .includes(messageId));
@@ -418,6 +423,7 @@ function useStream(options) {
418
423
  firstSeenState: firstSeen,
419
424
  branch: branch?.branch,
420
425
  branchOptions: branch?.branchOptions,
426
+ streamMetadata,
421
427
  };
422
428
  });
423
429
  })();
@@ -478,8 +484,8 @@ function useStream(options) {
478
484
  // if `streamSubgraphs: true`, then we also want
479
485
  // to also receive messages from subgraphs
480
486
  event.startsWith("messages|")) {
481
- const [serialized] = data;
482
- const messageId = messageManagerRef.current.add(serialized);
487
+ const [serialized, metadata] = data;
488
+ const messageId = messageManagerRef.current.add(serialized, metadata);
483
489
  if (!messageId) {
484
490
  console.warn("Failed to add message to manager, no message ID found");
485
491
  continue;
@@ -580,7 +586,11 @@ function useStream(options) {
580
586
  ...trackStreamModeRef.current,
581
587
  ...callbackStreamMode,
582
588
  ]);
583
- const checkpoint = submitOptions?.checkpoint ?? threadHead?.checkpoint ?? undefined;
589
+ let checkpoint = submitOptions?.checkpoint ?? threadHead?.checkpoint ?? undefined;
590
+ // Avoid specifying a checkpoint if user explicitly set it to null
591
+ if (submitOptions?.checkpoint === null) {
592
+ checkpoint = undefined;
593
+ }
584
594
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
585
595
  // @ts-expect-error
586
596
  if (checkpoint != null)
@@ -698,7 +708,7 @@ function useStream(options) {
698
708
  return getMessages(values);
699
709
  },
700
710
  getMessagesMetadata(message, index) {
701
- trackStreamMode("messages-tuple", "values");
711
+ trackStreamMode("values");
702
712
  return messageMetadata?.find((m) => m.messageId === (message.id ?? index));
703
713
  },
704
714
  };
@@ -34,6 +34,11 @@ export type MessageMetadata<StateType extends Record<string, unknown>> = {
34
34
  * This is useful for displaying branching controls.
35
35
  */
36
36
  branchOptions: string[] | undefined;
37
+ /**
38
+ * Metadata sent alongside the message during run streaming.
39
+ * @remarks This metadata only exists temporarily in browser memory during streaming and is not persisted after completion.
40
+ */
41
+ streamMetadata: Record<string, unknown> | undefined;
37
42
  };
38
43
  type BagTemplate = {
39
44
  ConfigurableType?: Record<string, unknown>;
@@ -30,7 +30,7 @@ class MessageTupleManager {
30
30
  });
31
31
  this.chunks = {};
32
32
  }
33
- add(serialized) {
33
+ add(serialized, metadata) {
34
34
  // TODO: this is sometimes sent from the API
35
35
  // figure out how to prevent this or move this to LC.js
36
36
  if (serialized.type.endsWith("MessageChunk")) {
@@ -47,6 +47,7 @@ class MessageTupleManager {
47
47
  return null;
48
48
  }
49
49
  this.chunks[id] ??= {};
50
+ this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;
50
51
  if (chunk) {
51
52
  const prev = this.chunks[id].chunk;
52
53
  this.chunks[id].chunk =
@@ -63,7 +64,8 @@ class MessageTupleManager {
63
64
  get(id, defaultIndex) {
64
65
  if (this.chunks[id] == null)
65
66
  return null;
66
- this.chunks[id].index ??= defaultIndex;
67
+ if (defaultIndex != null)
68
+ this.chunks[id].index ??= defaultIndex;
67
69
  return this.chunks[id];
68
70
  }
69
71
  }
@@ -392,6 +394,9 @@ export function useStream(options) {
392
394
  const alreadyShown = new Set();
393
395
  return getMessages(historyValues).map((message, idx) => {
394
396
  const messageId = message.id ?? idx;
397
+ const streamMetadata = message.id != null
398
+ ? messageManagerRef.current.get(message.id)?.metadata ?? undefined
399
+ : undefined;
395
400
  const firstSeenIdx = findLastIndex(history.data ?? [], (state) => getMessages(state.values)
396
401
  .map((m, idx) => m.id ?? idx)
397
402
  .includes(messageId));
@@ -414,6 +419,7 @@ export function useStream(options) {
414
419
  firstSeenState: firstSeen,
415
420
  branch: branch?.branch,
416
421
  branchOptions: branch?.branchOptions,
422
+ streamMetadata,
417
423
  };
418
424
  });
419
425
  })();
@@ -474,8 +480,8 @@ export function useStream(options) {
474
480
  // if `streamSubgraphs: true`, then we also want
475
481
  // to also receive messages from subgraphs
476
482
  event.startsWith("messages|")) {
477
- const [serialized] = data;
478
- const messageId = messageManagerRef.current.add(serialized);
483
+ const [serialized, metadata] = data;
484
+ const messageId = messageManagerRef.current.add(serialized, metadata);
479
485
  if (!messageId) {
480
486
  console.warn("Failed to add message to manager, no message ID found");
481
487
  continue;
@@ -576,7 +582,11 @@ export function useStream(options) {
576
582
  ...trackStreamModeRef.current,
577
583
  ...callbackStreamMode,
578
584
  ]);
579
- const checkpoint = submitOptions?.checkpoint ?? threadHead?.checkpoint ?? undefined;
585
+ let checkpoint = submitOptions?.checkpoint ?? threadHead?.checkpoint ?? undefined;
586
+ // Avoid specifying a checkpoint if user explicitly set it to null
587
+ if (submitOptions?.checkpoint === null) {
588
+ checkpoint = undefined;
589
+ }
580
590
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
581
591
  // @ts-expect-error
582
592
  if (checkpoint != null)
@@ -694,7 +704,7 @@ export function useStream(options) {
694
704
  return getMessages(values);
695
705
  },
696
706
  getMessagesMetadata(message, index) {
697
- trackStreamMode("messages-tuple", "values");
707
+ trackStreamMode("values");
698
708
  return messageMetadata?.find((m) => m.messageId === (message.id ?? index));
699
709
  },
700
710
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-sdk",
3
- "version": "0.0.105",
3
+ "version": "0.0.107",
4
4
  "description": "Client library for interacting with the LangGraph API",
5
5
  "type": "module",
6
6
  "scripts": {