@ai-sdk/langchain 2.0.267 → 2.0.269

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,22 @@
1
1
  # @ai-sdk/langchain
2
2
 
3
+ ## 2.0.269
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f1afbf9]
8
+ - ai@6.0.261
9
+
10
+ ## 2.0.268
11
+
12
+ ### Patch Changes
13
+
14
+ - 5b63247: Preserve tool input lifecycles when LangGraph steps reuse a provider tool call ID.
15
+ - Updated dependencies [98c656f]
16
+ - Updated dependencies [b253d52]
17
+ - Updated dependencies [9e15cb4]
18
+ - ai@6.0.260
19
+
3
20
  ## 2.0.267
4
21
 
5
22
  ### Patch Changes
package/dist/index.js CHANGED
@@ -615,6 +615,38 @@ function getOrCreateToolCallInfoByIndex(toolCallInfoByIndex, msgId) {
615
615
  function getLangGraphNamespaceKey(namespace) {
616
616
  return JSON.stringify(namespace != null ? namespace : []);
617
617
  }
618
+ function getOrCreateNamespaceSet(setsByNamespace, namespace) {
619
+ let values = setsByNamespace.get(namespace);
620
+ if (!values) {
621
+ values = /* @__PURE__ */ new Set();
622
+ setsByNamespace.set(namespace, values);
623
+ }
624
+ return values;
625
+ }
626
+ function hasEmittedToolCallInCurrentStep(state, toolCallId, namespace) {
627
+ var _a;
628
+ return !state.currentStepsByNamespace.has(namespace) ? state.emittedToolCalls.has(toolCallId) : ((_a = state.emittedToolCallsInCurrentStepByNamespace.get(namespace)) == null ? void 0 : _a.has(toolCallId)) === true;
629
+ }
630
+ function markToolCallEmitted(state, toolCallId, namespace) {
631
+ state.emittedToolCalls.add(toolCallId);
632
+ if (state.currentStepsByNamespace.has(namespace)) {
633
+ getOrCreateNamespaceSet(
634
+ state.emittedToolCallsInCurrentStepByNamespace,
635
+ namespace
636
+ ).add(toolCallId);
637
+ }
638
+ }
639
+ function findMessageCurrentStepNamespace(state, messageId) {
640
+ for (const [
641
+ namespace,
642
+ messageIds
643
+ ] of state.messageIdsInCurrentStepByNamespace) {
644
+ if (messageIds.has(messageId)) {
645
+ return namespace;
646
+ }
647
+ }
648
+ return void 0;
649
+ }
618
650
  function closeStepNamespaceMessages(state, stepNamespace, controller) {
619
651
  let hasConcurrentMessageParts = false;
620
652
  for (const [id, seen] of state.messageSeen) {
@@ -641,7 +673,7 @@ function closeStepNamespaceMessages(state, stepNamespace, controller) {
641
673
  return hasConcurrentMessageParts;
642
674
  }
643
675
  function processLangGraphEvent(event, state, controller) {
644
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
676
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
645
677
  const {
646
678
  messageSeen,
647
679
  messageConcat,
@@ -654,6 +686,7 @@ function processLangGraphEvent(event, state, controller) {
654
686
  } = state;
655
687
  const [rawNamespace, type, data] = parseLangGraphEvent(event);
656
688
  const namespace = Array.isArray(rawNamespace) && rawNamespace.every((segment) => typeof segment === "string") ? rawNamespace : void 0;
689
+ const eventNamespace = getLangGraphNamespaceKey(namespace);
657
690
  controller = createLangGraphNamespaceController(controller, state, namespace);
658
691
  switch (type) {
659
692
  case "custom": {
@@ -685,25 +718,47 @@ function processLangGraphEvent(event, state, controller) {
685
718
  state.messageNamespaces.set(msgId, namespace);
686
719
  }
687
720
  const langgraphStep = typeof (metadata == null ? void 0 : metadata.langgraph_step) === "number" ? metadata.langgraph_step : null;
688
- const eventNamespace = getLangGraphNamespaceKey(namespace);
689
- if (langgraphStep !== null && state.stepNamespace === null) {
690
- state.stepNamespace = eventNamespace;
691
- }
692
- if (langgraphStep !== null && eventNamespace === state.stepNamespace && langgraphStep !== state.currentStep) {
693
- if (state.currentStep !== null) {
721
+ if (langgraphStep !== null) {
722
+ const currentStep = (_a = state.currentStepsByNamespace.get(eventNamespace)) != null ? _a : null;
723
+ if (currentStep === null) {
724
+ if (state.currentStepsByNamespace.size === 0) {
725
+ controller.enqueue({ type: "start-step" });
726
+ }
727
+ state.currentStepsByNamespace.set(eventNamespace, langgraphStep);
728
+ state.messageIdsInCurrentStepByNamespace.set(
729
+ eventNamespace,
730
+ /* @__PURE__ */ new Set()
731
+ );
732
+ state.emittedToolCallsInCurrentStepByNamespace.set(
733
+ eventNamespace,
734
+ /* @__PURE__ */ new Set()
735
+ );
736
+ } else if (langgraphStep !== currentStep) {
694
737
  const hasConcurrentMessageParts = closeStepNamespaceMessages(
695
738
  state,
696
- state.stepNamespace,
739
+ eventNamespace,
697
740
  controller
698
741
  );
699
742
  if (!hasConcurrentMessageParts) {
700
743
  controller.enqueue({ type: "finish-step" });
701
- controller.enqueue({ type: "start-step" });
702
744
  }
703
- } else {
704
745
  controller.enqueue({ type: "start-step" });
746
+ state.currentStepsByNamespace.set(eventNamespace, langgraphStep);
747
+ state.messageIdsInCurrentStepByNamespace.set(
748
+ eventNamespace,
749
+ /* @__PURE__ */ new Set()
750
+ );
751
+ state.emittedToolCallsInCurrentStepByNamespace.set(
752
+ eventNamespace,
753
+ /* @__PURE__ */ new Set()
754
+ );
705
755
  }
706
- state.currentStep = langgraphStep;
756
+ }
757
+ if (state.currentStepsByNamespace.has(eventNamespace)) {
758
+ getOrCreateNamespaceSet(
759
+ state.messageIdsInCurrentStepByNamespace,
760
+ eventNamespace
761
+ ).add(msgId);
707
762
  }
708
763
  if (import_messages.AIMessageChunk.isInstance(msg)) {
709
764
  const existingMessage = messageConcat.get(msgId);
@@ -736,29 +791,33 @@ function processLangGraphEvent(event, state, controller) {
736
791
  const toolCallChunks = dataSource.tool_call_chunks;
737
792
  if (toolCallChunks == null ? void 0 : toolCallChunks.length) {
738
793
  for (const toolCallChunk of toolCallChunks) {
739
- const idx = (_a = toolCallChunk.index) != null ? _a : 0;
794
+ const idx = (_b = toolCallChunk.index) != null ? _b : 0;
740
795
  if (toolCallChunk.id) {
741
796
  getOrCreateToolCallInfoByIndex(toolCallInfoByIndex, msgId).set(
742
797
  idx,
743
798
  {
744
799
  id: toolCallChunk.id,
745
- name: toolCallChunk.name || ((_c = (_b = concatChunk == null ? void 0 : concatChunk.tool_call_chunks) == null ? void 0 : _b[idx]) == null ? void 0 : _c.name) || "unknown"
800
+ name: toolCallChunk.name || ((_d = (_c = concatChunk == null ? void 0 : concatChunk.tool_call_chunks) == null ? void 0 : _c[idx]) == null ? void 0 : _d.name) || "unknown"
746
801
  }
747
802
  );
748
803
  }
749
- const storedToolCallInfo = (_d = toolCallInfoByIndex.get(msgId)) == null ? void 0 : _d.get(idx);
750
- const toolCallId = toolCallChunk.id || (storedToolCallInfo == null ? void 0 : storedToolCallInfo.id) || ((_f = (_e = concatChunk == null ? void 0 : concatChunk.tool_call_chunks) == null ? void 0 : _e[idx]) == null ? void 0 : _f.id);
804
+ const storedToolCallInfo = (_e = toolCallInfoByIndex.get(msgId)) == null ? void 0 : _e.get(idx);
805
+ const toolCallId = toolCallChunk.id || (storedToolCallInfo == null ? void 0 : storedToolCallInfo.id) || ((_g = (_f = concatChunk == null ? void 0 : concatChunk.tool_call_chunks) == null ? void 0 : _f[idx]) == null ? void 0 : _g.id);
751
806
  if (!toolCallId) {
752
807
  continue;
753
808
  }
754
- const toolName = toolCallChunk.name || (storedToolCallInfo == null ? void 0 : storedToolCallInfo.name) || ((_h = (_g = concatChunk == null ? void 0 : concatChunk.tool_call_chunks) == null ? void 0 : _g[idx]) == null ? void 0 : _h.name) || "unknown";
809
+ const toolName = toolCallChunk.name || (storedToolCallInfo == null ? void 0 : storedToolCallInfo.name) || ((_i = (_h = concatChunk == null ? void 0 : concatChunk.tool_call_chunks) == null ? void 0 : _h[idx]) == null ? void 0 : _i.name) || "unknown";
755
810
  const seen = messageSeen.get(msgId);
756
- if (!((_i = seen == null ? void 0 : seen.tool) == null ? void 0 : _i.has(toolCallId))) {
811
+ if (!((_j = seen == null ? void 0 : seen.tool) == null ? void 0 : _j.has(toolCallId))) {
757
812
  const updatedSeen = getOrCreateMessageSeen(messageSeen, msgId);
758
- (_j = updatedSeen.tool) != null ? _j : updatedSeen.tool = /* @__PURE__ */ new Set();
813
+ (_k = updatedSeen.tool) != null ? _k : updatedSeen.tool = /* @__PURE__ */ new Set();
759
814
  updatedSeen.tool.add(toolCallId);
760
- if (!emittedToolCalls.has(toolCallId)) {
761
- emittedToolCalls.add(toolCallId);
815
+ if (!hasEmittedToolCallInCurrentStep(
816
+ state,
817
+ toolCallId,
818
+ eventNamespace
819
+ )) {
820
+ markToolCallEmitted(state, toolCallId, eventNamespace);
762
821
  controller.enqueue({
763
822
  type: "tool-input-start",
764
823
  toolCallId,
@@ -786,7 +845,7 @@ function processLangGraphEvent(event, state, controller) {
786
845
  }
787
846
  const reasoning = extractReasoningFromContentBlocks(msg);
788
847
  if (reasoning) {
789
- const reasoningId = (_l = (_k = messageReasoningIds.get(msgId)) != null ? _k : chunkReasoningId) != null ? _l : msgId;
848
+ const reasoningId = (_m = (_l = messageReasoningIds.get(msgId)) != null ? _l : chunkReasoningId) != null ? _m : msgId;
790
849
  const seen = messageSeen.get(msgId);
791
850
  if (!(seen == null ? void 0 : seen.reasoning)) {
792
851
  controller.enqueue({ type: "reasoning-start", id: msgId });
@@ -850,15 +909,18 @@ function processLangGraphEvent(event, state, controller) {
850
909
  }
851
910
  case "values": {
852
911
  for (const [id, seen] of messageSeen) {
912
+ const messageNamespace = getLangGraphNamespaceKey(
913
+ state.messageNamespaces.get(id)
914
+ );
853
915
  if (seen.text) controller.enqueue({ type: "text-end", id });
854
916
  if (seen.tool) {
855
917
  for (const toolCallId of seen.tool) {
856
918
  const concatMsg = messageConcat.get(id);
857
- const toolCall = (_m = concatMsg == null ? void 0 : concatMsg.tool_calls) == null ? void 0 : _m.find(
919
+ const toolCall = (_n = concatMsg == null ? void 0 : concatMsg.tool_calls) == null ? void 0 : _n.find(
858
920
  (call) => call.id === toolCallId
859
921
  );
860
922
  if (toolCall) {
861
- emittedToolCalls.add(toolCallId);
923
+ markToolCallEmitted(state, toolCallId, messageNamespace);
862
924
  const toolCallKey = `${toolCall.name}:${JSON.stringify(toolCall.args)}`;
863
925
  emittedToolCallsByKey.set(toolCallKey, toolCallId);
864
926
  controller.enqueue({
@@ -936,8 +998,18 @@ function processLangGraphEvent(event, state, controller) {
936
998
  }
937
999
  if (toolCalls && toolCalls.length > 0) {
938
1000
  for (const toolCall of toolCalls) {
939
- if (toolCall.id && !emittedToolCalls.has(toolCall.id) && !completedToolCallIds.has(toolCall.id)) {
940
- emittedToolCalls.add(toolCall.id);
1001
+ const messageNamespace = findMessageCurrentStepNamespace(
1002
+ state,
1003
+ msgId
1004
+ );
1005
+ const lifecycleNamespace = messageNamespace != null ? messageNamespace : eventNamespace;
1006
+ const wasObservedInCurrentStep = messageNamespace !== void 0;
1007
+ if (toolCall.id && !hasEmittedToolCallInCurrentStep(
1008
+ state,
1009
+ toolCall.id,
1010
+ lifecycleNamespace
1011
+ ) && (wasObservedInCurrentStep || !emittedToolCalls.has(toolCall.id) && !completedToolCallIds.has(toolCall.id))) {
1012
+ markToolCallEmitted(state, toolCall.id, lifecycleNamespace);
941
1013
  const toolCallKey = `${toolCall.name}:${JSON.stringify(toolCall.args)}`;
942
1014
  emittedToolCallsByKey.set(toolCallKey, toolCall.id);
943
1015
  controller.enqueue({
@@ -1002,7 +1074,7 @@ function processLangGraphEvent(event, state, controller) {
1002
1074
  const toolCallKey = `${toolName}:${JSON.stringify(input)}`;
1003
1075
  const toolCallId = emittedToolCallsByKey.get(toolCallKey) || actionRequest.id || `hitl-${toolName}-${Date.now()}`;
1004
1076
  if (!emittedToolCalls.has(toolCallId)) {
1005
- emittedToolCalls.add(toolCallId);
1077
+ markToolCallEmitted(state, toolCallId, eventNamespace);
1006
1078
  emittedToolCallsByKey.set(toolCallKey, toolCallId);
1007
1079
  controller.enqueue({
1008
1080
  type: "tool-input-start",
@@ -1213,13 +1285,14 @@ function toUIMessageStream(stream, callbacks) {
1213
1285
  messageSeen: /* @__PURE__ */ new Map(),
1214
1286
  messageNamespaces: /* @__PURE__ */ new Map(),
1215
1287
  messageConcat: /* @__PURE__ */ new Map(),
1288
+ messageIdsInCurrentStepByNamespace: /* @__PURE__ */ new Map(),
1216
1289
  emittedToolCalls: /* @__PURE__ */ new Set(),
1290
+ emittedToolCallsInCurrentStepByNamespace: /* @__PURE__ */ new Map(),
1217
1291
  emittedImages: /* @__PURE__ */ new Set(),
1218
1292
  emittedReasoningIds: /* @__PURE__ */ new Set(),
1219
1293
  messageReasoningIds: /* @__PURE__ */ new Map(),
1220
1294
  toolCallInfoByIndex: /* @__PURE__ */ new Map(),
1221
- currentStep: null,
1222
- stepNamespace: null,
1295
+ currentStepsByNamespace: /* @__PURE__ */ new Map(),
1223
1296
  emittedToolCallsByKey: /* @__PURE__ */ new Map(),
1224
1297
  emittedSourceIds: /* @__PURE__ */ new Set()
1225
1298
  };
@@ -1333,7 +1406,7 @@ function toUIMessageStream(stream, callbacks) {
1333
1406
  });
1334
1407
  }
1335
1408
  }
1336
- if (langGraphState.currentStep !== null) {
1409
+ if (langGraphState.currentStepsByNamespace.size > 0) {
1337
1410
  controller.enqueue({ type: "finish-step" });
1338
1411
  }
1339
1412
  controller.enqueue({ type: "finish" });