@langchain/langgraph 1.4.1 → 1.4.4

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.
Files changed (102) hide show
  1. package/dist/channels/delta.cjs +8 -9
  2. package/dist/channels/delta.cjs.map +1 -1
  3. package/dist/channels/delta.d.cts.map +1 -1
  4. package/dist/channels/delta.d.ts.map +1 -1
  5. package/dist/channels/delta.js +8 -9
  6. package/dist/channels/delta.js.map +1 -1
  7. package/dist/constants.cjs +10 -1
  8. package/dist/constants.cjs.map +1 -1
  9. package/dist/constants.d.cts.map +1 -1
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/constants.js +10 -1
  12. package/dist/constants.js.map +1 -1
  13. package/dist/graph/graph.cjs +3 -3
  14. package/dist/graph/graph.cjs.map +1 -1
  15. package/dist/graph/graph.js +1 -1
  16. package/dist/graph/graph.js.map +1 -1
  17. package/dist/graph/messages_reducer.cjs +15 -7
  18. package/dist/graph/messages_reducer.cjs.map +1 -1
  19. package/dist/graph/messages_reducer.d.cts +8 -3
  20. package/dist/graph/messages_reducer.d.cts.map +1 -1
  21. package/dist/graph/messages_reducer.d.ts +8 -3
  22. package/dist/graph/messages_reducer.d.ts.map +1 -1
  23. package/dist/graph/messages_reducer.js +13 -5
  24. package/dist/graph/messages_reducer.js.map +1 -1
  25. package/dist/index.cjs +3 -0
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +3 -2
  28. package/dist/index.d.ts +3 -2
  29. package/dist/index.js +3 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/pregel/algo.cjs +20 -3
  32. package/dist/pregel/algo.cjs.map +1 -1
  33. package/dist/pregel/algo.js +20 -3
  34. package/dist/pregel/algo.js.map +1 -1
  35. package/dist/pregel/debug.cjs +25 -1
  36. package/dist/pregel/debug.cjs.map +1 -1
  37. package/dist/pregel/debug.js +25 -1
  38. package/dist/pregel/debug.js.map +1 -1
  39. package/dist/pregel/index.cjs +8 -1
  40. package/dist/pregel/index.cjs.map +1 -1
  41. package/dist/pregel/index.d.cts.map +1 -1
  42. package/dist/pregel/index.d.ts.map +1 -1
  43. package/dist/pregel/index.js +9 -2
  44. package/dist/pregel/index.js.map +1 -1
  45. package/dist/pregel/loop.cjs +21 -3
  46. package/dist/pregel/loop.cjs.map +1 -1
  47. package/dist/pregel/loop.js +21 -3
  48. package/dist/pregel/loop.js.map +1 -1
  49. package/dist/pregel/messages-v2.cjs +1 -0
  50. package/dist/pregel/messages-v2.cjs.map +1 -1
  51. package/dist/pregel/messages-v2.js +1 -0
  52. package/dist/pregel/messages-v2.js.map +1 -1
  53. package/dist/pregel/utils/config.cjs +106 -9
  54. package/dist/pregel/utils/config.cjs.map +1 -1
  55. package/dist/pregel/utils/config.d.cts.map +1 -1
  56. package/dist/pregel/utils/config.d.ts.map +1 -1
  57. package/dist/pregel/utils/config.js +107 -11
  58. package/dist/pregel/utils/config.js.map +1 -1
  59. package/dist/pregel/utils/index.cjs +0 -16
  60. package/dist/pregel/utils/index.cjs.map +1 -1
  61. package/dist/pregel/utils/index.js +1 -16
  62. package/dist/pregel/utils/index.js.map +1 -1
  63. package/dist/state/index.cjs +1 -0
  64. package/dist/state/index.d.ts +2 -1
  65. package/dist/state/index.js +1 -0
  66. package/dist/state/prebuilt/index.d.ts +1 -1
  67. package/dist/state/prebuilt/messages.cjs +25 -0
  68. package/dist/state/prebuilt/messages.cjs.map +1 -1
  69. package/dist/state/prebuilt/messages.d.cts +18 -1
  70. package/dist/state/prebuilt/messages.d.cts.map +1 -1
  71. package/dist/state/prebuilt/messages.d.ts +18 -1
  72. package/dist/state/prebuilt/messages.d.ts.map +1 -1
  73. package/dist/state/prebuilt/messages.js +31 -4
  74. package/dist/state/prebuilt/messages.js.map +1 -1
  75. package/dist/state/schema.cjs +14 -6
  76. package/dist/state/schema.cjs.map +1 -1
  77. package/dist/state/schema.d.cts +7 -4
  78. package/dist/state/schema.d.cts.map +1 -1
  79. package/dist/state/schema.d.ts +7 -4
  80. package/dist/state/schema.d.ts.map +1 -1
  81. package/dist/state/schema.js +14 -6
  82. package/dist/state/schema.js.map +1 -1
  83. package/dist/state/values/delta.cjs +77 -0
  84. package/dist/state/values/delta.cjs.map +1 -0
  85. package/dist/state/values/delta.d.cts +152 -0
  86. package/dist/state/values/delta.d.cts.map +1 -0
  87. package/dist/state/values/delta.d.ts +152 -0
  88. package/dist/state/values/delta.d.ts.map +1 -0
  89. package/dist/state/values/delta.js +77 -0
  90. package/dist/state/values/delta.js.map +1 -0
  91. package/dist/state/values/index.cjs +1 -0
  92. package/dist/state/values/index.d.ts +3 -0
  93. package/dist/state/values/index.js +1 -0
  94. package/dist/stream/transformers/lifecycle.cjs +93 -2
  95. package/dist/stream/transformers/lifecycle.cjs.map +1 -1
  96. package/dist/stream/transformers/lifecycle.js +93 -2
  97. package/dist/stream/transformers/lifecycle.js.map +1 -1
  98. package/dist/web.cjs +3 -0
  99. package/dist/web.d.cts +3 -2
  100. package/dist/web.d.ts +3 -2
  101. package/dist/web.js +3 -2
  102. package/package.json +4 -6
@@ -1,4 +1,4 @@
1
- let uuid = require("uuid");
1
+ let _langchain_core_utils_uuid = require("@langchain/core/utils/uuid");
2
2
  let _langchain_core_messages = require("@langchain/core/messages");
3
3
  //#region src/graph/messages_reducer.ts
4
4
  /**
@@ -46,14 +46,14 @@ function messagesStateReducer(left, right) {
46
46
  const leftMessages = leftArray.map(_langchain_core_messages.coerceMessageLikeToMessage);
47
47
  const rightMessages = rightArray.map(_langchain_core_messages.coerceMessageLikeToMessage);
48
48
  for (const m of leftMessages) if (m.id === null || m.id === void 0) {
49
- m.id = (0, uuid.v4)();
49
+ m.id = (0, _langchain_core_utils_uuid.v4)();
50
50
  m.lc_kwargs.id = m.id;
51
51
  }
52
52
  let removeAllIdx;
53
53
  for (let i = 0; i < rightMessages.length; i += 1) {
54
54
  const m = rightMessages[i];
55
55
  if (m.id === null || m.id === void 0) {
56
- m.id = (0, uuid.v4)();
56
+ m.id = (0, _langchain_core_utils_uuid.v4)();
57
57
  m.lc_kwargs.id = m.id;
58
58
  }
59
59
  if (_langchain_core_messages.RemoveMessage.isInstance(m) && m.id === "__remove_all__") removeAllIdx = i;
@@ -86,11 +86,16 @@ function messagesStateReducer(left, right) {
86
86
  * This reducer is batching-invariant, as required by `DeltaChannel`:
87
87
  * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.
88
88
  *
89
+ * A `RemoveMessage` carrying the {@link REMOVE_ALL_MESSAGES} sentinel id
90
+ * clears all messages accumulated so far (prior state plus earlier writes in
91
+ * the same batch) and keeps only the messages that follow it, mirroring
92
+ * {@link messagesStateReducer}. Clearing happens in the same single linear
93
+ * pass, so the batching-invariant still holds.
94
+ *
89
95
  * Raw object / string inputs are coerced to typed `BaseMessage` objects so
90
96
  * that HTTP-driven graphs work without a separate coercion step. This is not
91
- * full {@link messagesStateReducer} parity — `REMOVE_ALL_MESSAGES`,
92
- * unknown-id `RemoveMessage` errors, and missing-id UUID assignment are not
93
- * handled here.
97
+ * full {@link messagesStateReducer} parity — unknown-id `RemoveMessage`
98
+ * errors and missing-id UUID assignment are not handled here.
94
99
  *
95
100
  * @param state - The current accumulated list of messages.
96
101
  * @param writes - Batch of writes, each a single message-like or an array.
@@ -117,7 +122,10 @@ function messagesDeltaReducer(state, writes) {
117
122
  const result = [...stateMsgs];
118
123
  for (const msg of msgs) {
119
124
  const mid = msg.id;
120
- if (mid == null) result.push(msg);
125
+ if (_langchain_core_messages.RemoveMessage.isInstance(msg) && mid === "__remove_all__") {
126
+ result.length = 0;
127
+ index.clear();
128
+ } else if (mid == null) result.push(msg);
121
129
  else if (_langchain_core_messages.RemoveMessage.isInstance(msg)) {
122
130
  if (index.has(mid)) {
123
131
  result[index.get(mid)] = null;
@@ -1 +1 @@
1
- {"version":3,"file":"messages_reducer.cjs","names":["coerceMessageLikeToMessage","RemoveMessage","BaseMessage"],"sources":["../../src/graph/messages_reducer.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n RemoveMessage,\n} from \"@langchain/core/messages\";\nimport { v4 } from \"uuid\";\n\n/**\n * Special value that signifies the intent to remove all previous messages in the state reducer.\n * Used as the unique identifier for a `RemoveMessage` instance which, when encountered,\n * causes all prior messages to be discarded, leaving only those following this marker.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\n/**\n * Type that represents an acceptable input for the messages state reducer.\n *\n * - Can be a single `BaseMessage` or `BaseMessageLike`.\n * - Can be an array of `BaseMessage` or `BaseMessageLike`.\n */\nexport type Messages =\n | Array<BaseMessage | BaseMessageLike>\n | BaseMessage\n | BaseMessageLike;\n\n/**\n * Reducer function for combining two sets of messages in LangGraph's state system.\n *\n * This reducer handles several tasks:\n * 1. Normalizes both `left` and `right` message inputs to arrays.\n * 2. Coerces any message-like objects into real `BaseMessage` instances.\n * 3. Ensures all messages have unique, stable IDs by generating missing ones.\n * 4. If a `RemoveMessage` instance is encountered in `right` with the ID `REMOVE_ALL_MESSAGES`,\n * all previous messages are discarded and only the subsequent messages in `right` are returned.\n * 5. Otherwise, merges `left` and `right` messages together following these rules:\n * - If a message in `right` shares an ID with a message in `left`:\n * - If it is a `RemoveMessage`, that message (by ID) is marked for removal.\n * - If it is a normal message, it replaces the message with the same ID from `left`.\n * - If a message in `right` **does not exist** in `left`:\n * - If it is a `RemoveMessage`, this is considered an error (cannot remove non-existent ID).\n * - Otherwise, the message is appended.\n * - Messages flagged for removal are omitted from the final output.\n *\n * @param left - The existing array (or single message) of messages from current state.\n * @param right - The new array (or single message) of messages to be applied.\n * @returns A new array of `BaseMessage` objects representing the updated state.\n *\n * @throws Error if a `RemoveMessage` is used to delete a message with an ID that does not exist in the merged list.\n *\n * @example\n * ```ts\n * const msg1 = new AIMessage(\"hello\");\n * const msg2 = new HumanMessage(\"hi\");\n * const removal = new RemoveMessage({ id: msg1.id });\n * const newState = messagesStateReducer([msg1], [msg2, removal]);\n * // newState will only contain msg2 (msg1 is removed)\n * ```\n */\nexport function messagesStateReducer(\n left: Messages,\n right: Messages\n): BaseMessage[] {\n // Ensure both left and right are arrays\n const leftArray = Array.isArray(left) ? left : [left];\n const rightArray = Array.isArray(right) ? right : [right];\n\n // Convert all input to BaseMessage instances\n const leftMessages = (leftArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n const rightMessages = (rightArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n\n // Assign missing IDs to any message in the left array\n for (const m of leftMessages) {\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n }\n\n // Assign missing IDs and check for \"remove all\" marker in right array\n let removeAllIdx: number | undefined;\n for (let i = 0; i < rightMessages.length; i += 1) {\n const m = rightMessages[i];\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n\n // If RemoveMessage with special REMOVE_ALL_MESSAGES id is found\n if (RemoveMessage.isInstance(m) && m.id === REMOVE_ALL_MESSAGES) {\n removeAllIdx = i;\n }\n }\n\n // If remove-all is present, all previous messages are wiped; return only subsequent ones\n if (removeAllIdx != null) return rightMessages.slice(removeAllIdx + 1);\n\n // Begin normal merging logic\n const merged = [...leftMessages];\n const mergedById = new Map(merged.map((m, i) => [m.id, i]));\n const idsToRemove = new Set();\n\n for (const m of rightMessages) {\n const existingIdx = mergedById.get(m.id);\n if (existingIdx !== undefined) {\n // Case: updating or removing an existing message by id\n if (RemoveMessage.isInstance(m)) {\n idsToRemove.add(m.id);\n } else {\n idsToRemove.delete(m.id);\n merged[existingIdx] = m;\n }\n } else {\n // Case: inserting a completely new message\n if (RemoveMessage.isInstance(m)) {\n throw new Error(\n `Attempting to delete a message with an ID that doesn't exist ('${m.id}')`\n );\n }\n mergedById.set(m.id, merged.length);\n merged.push(m);\n }\n }\n\n // Remove any messages whose IDs are marked for removal\n return merged.filter((m) => !idsToRemove.has(m.id));\n}\n\n/**\n * **Experimental.** Batch reducer for use with `DeltaChannel`.\n *\n * Processes all writes in one pass — dedup by ID and `RemoveMessage`\n * tombstoning — without calling {@link messagesStateReducer}.\n *\n * This reducer is batching-invariant, as required by `DeltaChannel`:\n * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.\n *\n * Raw object / string inputs are coerced to typed `BaseMessage` objects so\n * that HTTP-driven graphs work without a separate coercion step. This is not\n * full {@link messagesStateReducer} parity — `REMOVE_ALL_MESSAGES`,\n * unknown-id `RemoveMessage` errors, and missing-id UUID assignment are not\n * handled here.\n *\n * @param state - The current accumulated list of messages.\n * @param writes - Batch of writes, each a single message-like or an array.\n * @returns The new accumulated list of messages.\n *\n * @example\n * ```typescript\n * import { DeltaChannel, messagesDeltaReducer } from \"@langchain/langgraph\";\n *\n * const channel = new DeltaChannel(messagesDeltaReducer);\n * ```\n */\nexport function messagesDeltaReducer(\n state: BaseMessage[],\n writes: Messages[]\n): BaseMessage[] {\n // Each write is either an array of message-likes or a single message-like.\n // Only arrays flatten; everything else is one message.\n const flat: BaseMessageLike[] = [];\n for (const w of writes) {\n if (Array.isArray(w)) {\n flat.push(...(w as BaseMessageLike[]));\n } else {\n flat.push(w as BaseMessageLike);\n }\n }\n\n // Steady state: the reducer's own output is already typed, so skip coercion\n // on state when the first element is a BaseMessage. Only raw input (initial\n // objects, deserialized blobs) hits the slow path.\n const stateMsgs: BaseMessage[] =\n state.length > 0 && BaseMessage.isInstance(state[0])\n ? state\n : (state as BaseMessageLike[]).map(coerceMessageLikeToMessage);\n const msgs: BaseMessage[] = flat.map(coerceMessageLikeToMessage);\n\n const index = new Map<string, number>();\n for (let i = 0; i < stateMsgs.length; i += 1) {\n const mid = stateMsgs[i].id;\n if (mid != null) index.set(mid, i);\n }\n\n const result: (BaseMessage | null)[] = [...stateMsgs];\n for (const msg of msgs) {\n const mid = msg.id;\n if (mid == null) {\n result.push(msg);\n } else if (RemoveMessage.isInstance(msg)) {\n if (index.has(mid)) {\n result[index.get(mid)!] = null;\n index.delete(mid);\n }\n } else if (index.has(mid)) {\n result[index.get(mid)!] = msg;\n } else {\n index.set(mid, result.length);\n result.push(msg);\n }\n }\n return result.filter((m): m is BaseMessage => m !== null);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"messages_reducer.cjs","names":["coerceMessageLikeToMessage","RemoveMessage","BaseMessage"],"sources":["../../src/graph/messages_reducer.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n RemoveMessage,\n} from \"@langchain/core/messages\";\nimport { v4 } from \"@langchain/core/utils/uuid\";\n\n/**\n * Special value that signifies the intent to remove all previous messages in the state reducer.\n * Used as the unique identifier for a `RemoveMessage` instance which, when encountered,\n * causes all prior messages to be discarded, leaving only those following this marker.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\n/**\n * Type that represents an acceptable input for the messages state reducer.\n *\n * - Can be a single `BaseMessage` or `BaseMessageLike`.\n * - Can be an array of `BaseMessage` or `BaseMessageLike`.\n */\nexport type Messages =\n | Array<BaseMessage | BaseMessageLike>\n | BaseMessage\n | BaseMessageLike;\n\n/**\n * Reducer function for combining two sets of messages in LangGraph's state system.\n *\n * This reducer handles several tasks:\n * 1. Normalizes both `left` and `right` message inputs to arrays.\n * 2. Coerces any message-like objects into real `BaseMessage` instances.\n * 3. Ensures all messages have unique, stable IDs by generating missing ones.\n * 4. If a `RemoveMessage` instance is encountered in `right` with the ID `REMOVE_ALL_MESSAGES`,\n * all previous messages are discarded and only the subsequent messages in `right` are returned.\n * 5. Otherwise, merges `left` and `right` messages together following these rules:\n * - If a message in `right` shares an ID with a message in `left`:\n * - If it is a `RemoveMessage`, that message (by ID) is marked for removal.\n * - If it is a normal message, it replaces the message with the same ID from `left`.\n * - If a message in `right` **does not exist** in `left`:\n * - If it is a `RemoveMessage`, this is considered an error (cannot remove non-existent ID).\n * - Otherwise, the message is appended.\n * - Messages flagged for removal are omitted from the final output.\n *\n * @param left - The existing array (or single message) of messages from current state.\n * @param right - The new array (or single message) of messages to be applied.\n * @returns A new array of `BaseMessage` objects representing the updated state.\n *\n * @throws Error if a `RemoveMessage` is used to delete a message with an ID that does not exist in the merged list.\n *\n * @example\n * ```ts\n * const msg1 = new AIMessage(\"hello\");\n * const msg2 = new HumanMessage(\"hi\");\n * const removal = new RemoveMessage({ id: msg1.id });\n * const newState = messagesStateReducer([msg1], [msg2, removal]);\n * // newState will only contain msg2 (msg1 is removed)\n * ```\n */\nexport function messagesStateReducer(\n left: Messages,\n right: Messages\n): BaseMessage[] {\n // Ensure both left and right are arrays\n const leftArray = Array.isArray(left) ? left : [left];\n const rightArray = Array.isArray(right) ? right : [right];\n\n // Convert all input to BaseMessage instances\n const leftMessages = (leftArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n const rightMessages = (rightArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n\n // Assign missing IDs to any message in the left array\n for (const m of leftMessages) {\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n }\n\n // Assign missing IDs and check for \"remove all\" marker in right array\n let removeAllIdx: number | undefined;\n for (let i = 0; i < rightMessages.length; i += 1) {\n const m = rightMessages[i];\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n\n // If RemoveMessage with special REMOVE_ALL_MESSAGES id is found\n if (RemoveMessage.isInstance(m) && m.id === REMOVE_ALL_MESSAGES) {\n removeAllIdx = i;\n }\n }\n\n // If remove-all is present, all previous messages are wiped; return only subsequent ones\n if (removeAllIdx != null) return rightMessages.slice(removeAllIdx + 1);\n\n // Begin normal merging logic\n const merged = [...leftMessages];\n const mergedById = new Map(merged.map((m, i) => [m.id, i]));\n const idsToRemove = new Set();\n\n for (const m of rightMessages) {\n const existingIdx = mergedById.get(m.id);\n if (existingIdx !== undefined) {\n // Case: updating or removing an existing message by id\n if (RemoveMessage.isInstance(m)) {\n idsToRemove.add(m.id);\n } else {\n idsToRemove.delete(m.id);\n merged[existingIdx] = m;\n }\n } else {\n // Case: inserting a completely new message\n if (RemoveMessage.isInstance(m)) {\n throw new Error(\n `Attempting to delete a message with an ID that doesn't exist ('${m.id}')`\n );\n }\n mergedById.set(m.id, merged.length);\n merged.push(m);\n }\n }\n\n // Remove any messages whose IDs are marked for removal\n return merged.filter((m) => !idsToRemove.has(m.id));\n}\n\n/**\n * **Experimental.** Batch reducer for use with `DeltaChannel`.\n *\n * Processes all writes in one pass — dedup by ID and `RemoveMessage`\n * tombstoning — without calling {@link messagesStateReducer}.\n *\n * This reducer is batching-invariant, as required by `DeltaChannel`:\n * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.\n *\n * A `RemoveMessage` carrying the {@link REMOVE_ALL_MESSAGES} sentinel id\n * clears all messages accumulated so far (prior state plus earlier writes in\n * the same batch) and keeps only the messages that follow it, mirroring\n * {@link messagesStateReducer}. Clearing happens in the same single linear\n * pass, so the batching-invariant still holds.\n *\n * Raw object / string inputs are coerced to typed `BaseMessage` objects so\n * that HTTP-driven graphs work without a separate coercion step. This is not\n * full {@link messagesStateReducer} parity — unknown-id `RemoveMessage`\n * errors and missing-id UUID assignment are not handled here.\n *\n * @param state - The current accumulated list of messages.\n * @param writes - Batch of writes, each a single message-like or an array.\n * @returns The new accumulated list of messages.\n *\n * @example\n * ```typescript\n * import { DeltaChannel, messagesDeltaReducer } from \"@langchain/langgraph\";\n *\n * const channel = new DeltaChannel(messagesDeltaReducer);\n * ```\n */\nexport function messagesDeltaReducer(\n state: BaseMessage[],\n writes: Messages[]\n): BaseMessage[] {\n // Each write is either an array of message-likes or a single message-like.\n // Only arrays flatten; everything else is one message.\n const flat: BaseMessageLike[] = [];\n for (const w of writes) {\n if (Array.isArray(w)) {\n flat.push(...(w as BaseMessageLike[]));\n } else {\n flat.push(w as BaseMessageLike);\n }\n }\n\n // Steady state: the reducer's own output is already typed, so skip coercion\n // on state when the first element is a BaseMessage. Only raw input (initial\n // objects, deserialized blobs) hits the slow path.\n const stateMsgs: BaseMessage[] =\n state.length > 0 && BaseMessage.isInstance(state[0])\n ? state\n : (state as BaseMessageLike[]).map(coerceMessageLikeToMessage);\n const msgs: BaseMessage[] = flat.map(coerceMessageLikeToMessage);\n\n const index = new Map<string, number>();\n for (let i = 0; i < stateMsgs.length; i += 1) {\n const mid = stateMsgs[i].id;\n if (mid != null) index.set(mid, i);\n }\n\n const result: (BaseMessage | null)[] = [...stateMsgs];\n for (const msg of msgs) {\n const mid = msg.id;\n if (RemoveMessage.isInstance(msg) && mid === REMOVE_ALL_MESSAGES) {\n // Discard everything accumulated so far (prior state and earlier writes\n // in this batch); only messages following the sentinel are kept. Doing\n // this inline keeps the reducer batching-invariant.\n result.length = 0;\n index.clear();\n } else if (mid == null) {\n result.push(msg);\n } else if (RemoveMessage.isInstance(msg)) {\n if (index.has(mid)) {\n result[index.get(mid)!] = null;\n index.delete(mid);\n }\n } else if (index.has(mid)) {\n result[index.get(mid)!] = msg;\n } else {\n index.set(mid, result.length);\n result.push(msg);\n }\n }\n return result.filter((m): m is BaseMessage => m !== null);\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CnC,SAAgB,qBACd,MACA,OACe;CAEf,MAAM,YAAY,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;CACrD,MAAM,aAAa,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;CAGzD,MAAM,eAAgB,UAAgC,IACpDA,yBAAAA,2BACD;CACD,MAAM,gBAAiB,WAAiC,IACtDA,yBAAAA,2BACD;AAGD,MAAK,MAAM,KAAK,aACd,KAAI,EAAE,OAAO,QAAQ,EAAE,OAAO,KAAA,GAAW;AACvC,IAAE,MAAA,GAAA,2BAAA,KAAS;AACX,IAAE,UAAU,KAAK,EAAE;;CAKvB,IAAI;AACJ,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK,GAAG;EAChD,MAAM,IAAI,cAAc;AACxB,MAAI,EAAE,OAAO,QAAQ,EAAE,OAAO,KAAA,GAAW;AACvC,KAAE,MAAA,GAAA,2BAAA,KAAS;AACX,KAAE,UAAU,KAAK,EAAE;;AAIrB,MAAIC,yBAAAA,cAAc,WAAW,EAAE,IAAI,EAAE,OAAA,iBACnC,gBAAe;;AAKnB,KAAI,gBAAgB,KAAM,QAAO,cAAc,MAAM,eAAe,EAAE;CAGtE,MAAM,SAAS,CAAC,GAAG,aAAa;CAChC,MAAM,aAAa,IAAI,IAAI,OAAO,KAAK,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;CAC3D,MAAM,8BAAc,IAAI,KAAK;AAE7B,MAAK,MAAM,KAAK,eAAe;EAC7B,MAAM,cAAc,WAAW,IAAI,EAAE,GAAG;AACxC,MAAI,gBAAgB,KAAA,EAElB,KAAIA,yBAAAA,cAAc,WAAW,EAAE,CAC7B,aAAY,IAAI,EAAE,GAAG;OAChB;AACL,eAAY,OAAO,EAAE,GAAG;AACxB,UAAO,eAAe;;OAEnB;AAEL,OAAIA,yBAAAA,cAAc,WAAW,EAAE,CAC7B,OAAM,IAAI,MACR,kEAAkE,EAAE,GAAG,IACxE;AAEH,cAAW,IAAI,EAAE,IAAI,OAAO,OAAO;AACnC,UAAO,KAAK,EAAE;;;AAKlB,QAAO,OAAO,QAAQ,MAAM,CAAC,YAAY,IAAI,EAAE,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCrD,SAAgB,qBACd,OACA,QACe;CAGf,MAAM,OAA0B,EAAE;AAClC,MAAK,MAAM,KAAK,OACd,KAAI,MAAM,QAAQ,EAAE,CAClB,MAAK,KAAK,GAAI,EAAwB;KAEtC,MAAK,KAAK,EAAqB;CAOnC,MAAM,YACJ,MAAM,SAAS,KAAKC,yBAAAA,YAAY,WAAW,MAAM,GAAG,GAChD,QACC,MAA4B,IAAIF,yBAAAA,2BAA2B;CAClE,MAAM,OAAsB,KAAK,IAAIA,yBAAAA,2BAA2B;CAEhE,MAAM,wBAAQ,IAAI,KAAqB;AACvC,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,GAAG;EAC5C,MAAM,MAAM,UAAU,GAAG;AACzB,MAAI,OAAO,KAAM,OAAM,IAAI,KAAK,EAAE;;CAGpC,MAAM,SAAiC,CAAC,GAAG,UAAU;AACrD,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAM,IAAI;AAChB,MAAIC,yBAAAA,cAAc,WAAW,IAAI,IAAI,QAAA,kBAA6B;AAIhE,UAAO,SAAS;AAChB,SAAM,OAAO;aACJ,OAAO,KAChB,QAAO,KAAK,IAAI;WACPA,yBAAAA,cAAc,WAAW,IAAI;OAClC,MAAM,IAAI,IAAI,EAAE;AAClB,WAAO,MAAM,IAAI,IAAI,IAAK;AAC1B,UAAM,OAAO,IAAI;;aAEV,MAAM,IAAI,IAAI,CACvB,QAAO,MAAM,IAAI,IAAI,IAAK;OACrB;AACL,SAAM,IAAI,KAAK,OAAO,OAAO;AAC7B,UAAO,KAAK,IAAI;;;AAGpB,QAAO,OAAO,QAAQ,MAAwB,MAAM,KAAK"}
@@ -57,11 +57,16 @@ declare function messagesStateReducer(left: Messages, right: Messages): BaseMess
57
57
  * This reducer is batching-invariant, as required by `DeltaChannel`:
58
58
  * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.
59
59
  *
60
+ * A `RemoveMessage` carrying the {@link REMOVE_ALL_MESSAGES} sentinel id
61
+ * clears all messages accumulated so far (prior state plus earlier writes in
62
+ * the same batch) and keeps only the messages that follow it, mirroring
63
+ * {@link messagesStateReducer}. Clearing happens in the same single linear
64
+ * pass, so the batching-invariant still holds.
65
+ *
60
66
  * Raw object / string inputs are coerced to typed `BaseMessage` objects so
61
67
  * that HTTP-driven graphs work without a separate coercion step. This is not
62
- * full {@link messagesStateReducer} parity — `REMOVE_ALL_MESSAGES`,
63
- * unknown-id `RemoveMessage` errors, and missing-id UUID assignment are not
64
- * handled here.
68
+ * full {@link messagesStateReducer} parity — unknown-id `RemoveMessage`
69
+ * errors and missing-id UUID assignment are not handled here.
65
70
  *
66
71
  * @param state - The current accumulated list of messages.
67
72
  * @param writes - Batch of writes, each a single message-like or an array.
@@ -1 +1 @@
1
- {"version":3,"file":"messages_reducer.d.cts","names":[],"sources":["../../src/graph/messages_reducer.ts"],"mappings":";;;;;AAaA;;;cAAa,mBAAA;;AAQb;;;;;KAAY,QAAA,GACR,KAAA,CAAM,WAAA,GAAc,eAAA,IACpB,WAAA,GACA,eAAA;;;;;;;;;;;;AAmCJ;;;;;;;;;;;;;;;AAmGA;;;;;;;iBAnGgB,oBAAA,CACd,IAAA,EAAM,QAAA,EACN,KAAA,EAAO,QAAA,GACN,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgGa,oBAAA,CACd,KAAA,EAAO,WAAA,IACP,MAAA,EAAQ,QAAA,KACP,WAAA"}
1
+ {"version":3,"file":"messages_reducer.d.cts","names":[],"sources":["../../src/graph/messages_reducer.ts"],"mappings":";;;;;AAaA;;;cAAa,mBAAA;;AAQb;;;;;KAAY,QAAA,GACR,KAAA,CAAM,WAAA,GAAc,eAAA,IACpB,WAAA,GACA,eAAA;;;;;;;;;;;;AAmCJ;;;;;;;;;;;;;;;AAwGA;;;;;;;iBAxGgB,oBAAA,CACd,IAAA,EAAM,QAAA,EACN,KAAA,EAAO,QAAA,GACN,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqGa,oBAAA,CACd,KAAA,EAAO,WAAA,IACP,MAAA,EAAQ,QAAA,KACP,WAAA"}
@@ -57,11 +57,16 @@ declare function messagesStateReducer(left: Messages, right: Messages): BaseMess
57
57
  * This reducer is batching-invariant, as required by `DeltaChannel`:
58
58
  * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.
59
59
  *
60
+ * A `RemoveMessage` carrying the {@link REMOVE_ALL_MESSAGES} sentinel id
61
+ * clears all messages accumulated so far (prior state plus earlier writes in
62
+ * the same batch) and keeps only the messages that follow it, mirroring
63
+ * {@link messagesStateReducer}. Clearing happens in the same single linear
64
+ * pass, so the batching-invariant still holds.
65
+ *
60
66
  * Raw object / string inputs are coerced to typed `BaseMessage` objects so
61
67
  * that HTTP-driven graphs work without a separate coercion step. This is not
62
- * full {@link messagesStateReducer} parity — `REMOVE_ALL_MESSAGES`,
63
- * unknown-id `RemoveMessage` errors, and missing-id UUID assignment are not
64
- * handled here.
68
+ * full {@link messagesStateReducer} parity — unknown-id `RemoveMessage`
69
+ * errors and missing-id UUID assignment are not handled here.
65
70
  *
66
71
  * @param state - The current accumulated list of messages.
67
72
  * @param writes - Batch of writes, each a single message-like or an array.
@@ -1 +1 @@
1
- {"version":3,"file":"messages_reducer.d.ts","names":[],"sources":["../../src/graph/messages_reducer.ts"],"mappings":";;;;;AAaA;;;cAAa,mBAAA;;AAQb;;;;;KAAY,QAAA,GACR,KAAA,CAAM,WAAA,GAAc,eAAA,IACpB,WAAA,GACA,eAAA;;;;;;;;;;;;AAmCJ;;;;;;;;;;;;;;;AAmGA;;;;;;;iBAnGgB,oBAAA,CACd,IAAA,EAAM,QAAA,EACN,KAAA,EAAO,QAAA,GACN,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgGa,oBAAA,CACd,KAAA,EAAO,WAAA,IACP,MAAA,EAAQ,QAAA,KACP,WAAA"}
1
+ {"version":3,"file":"messages_reducer.d.ts","names":[],"sources":["../../src/graph/messages_reducer.ts"],"mappings":";;;;;AAaA;;;cAAa,mBAAA;;AAQb;;;;;KAAY,QAAA,GACR,KAAA,CAAM,WAAA,GAAc,eAAA,IACpB,WAAA,GACA,eAAA;;;;;;;;;;;;AAmCJ;;;;;;;;;;;;;;;AAwGA;;;;;;;iBAxGgB,oBAAA,CACd,IAAA,EAAM,QAAA,EACN,KAAA,EAAO,QAAA,GACN,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqGa,oBAAA,CACd,KAAA,EAAO,WAAA,IACP,MAAA,EAAQ,QAAA,KACP,WAAA"}
@@ -1,4 +1,4 @@
1
- import { v4 } from "uuid";
1
+ import { v4 } from "@langchain/core/utils/uuid";
2
2
  import { BaseMessage, RemoveMessage, coerceMessageLikeToMessage } from "@langchain/core/messages";
3
3
  //#region src/graph/messages_reducer.ts
4
4
  /**
@@ -86,11 +86,16 @@ function messagesStateReducer(left, right) {
86
86
  * This reducer is batching-invariant, as required by `DeltaChannel`:
87
87
  * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.
88
88
  *
89
+ * A `RemoveMessage` carrying the {@link REMOVE_ALL_MESSAGES} sentinel id
90
+ * clears all messages accumulated so far (prior state plus earlier writes in
91
+ * the same batch) and keeps only the messages that follow it, mirroring
92
+ * {@link messagesStateReducer}. Clearing happens in the same single linear
93
+ * pass, so the batching-invariant still holds.
94
+ *
89
95
  * Raw object / string inputs are coerced to typed `BaseMessage` objects so
90
96
  * that HTTP-driven graphs work without a separate coercion step. This is not
91
- * full {@link messagesStateReducer} parity — `REMOVE_ALL_MESSAGES`,
92
- * unknown-id `RemoveMessage` errors, and missing-id UUID assignment are not
93
- * handled here.
97
+ * full {@link messagesStateReducer} parity — unknown-id `RemoveMessage`
98
+ * errors and missing-id UUID assignment are not handled here.
94
99
  *
95
100
  * @param state - The current accumulated list of messages.
96
101
  * @param writes - Batch of writes, each a single message-like or an array.
@@ -117,7 +122,10 @@ function messagesDeltaReducer(state, writes) {
117
122
  const result = [...stateMsgs];
118
123
  for (const msg of msgs) {
119
124
  const mid = msg.id;
120
- if (mid == null) result.push(msg);
125
+ if (RemoveMessage.isInstance(msg) && mid === "__remove_all__") {
126
+ result.length = 0;
127
+ index.clear();
128
+ } else if (mid == null) result.push(msg);
121
129
  else if (RemoveMessage.isInstance(msg)) {
122
130
  if (index.has(mid)) {
123
131
  result[index.get(mid)] = null;
@@ -1 +1 @@
1
- {"version":3,"file":"messages_reducer.js","names":[],"sources":["../../src/graph/messages_reducer.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n RemoveMessage,\n} from \"@langchain/core/messages\";\nimport { v4 } from \"uuid\";\n\n/**\n * Special value that signifies the intent to remove all previous messages in the state reducer.\n * Used as the unique identifier for a `RemoveMessage` instance which, when encountered,\n * causes all prior messages to be discarded, leaving only those following this marker.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\n/**\n * Type that represents an acceptable input for the messages state reducer.\n *\n * - Can be a single `BaseMessage` or `BaseMessageLike`.\n * - Can be an array of `BaseMessage` or `BaseMessageLike`.\n */\nexport type Messages =\n | Array<BaseMessage | BaseMessageLike>\n | BaseMessage\n | BaseMessageLike;\n\n/**\n * Reducer function for combining two sets of messages in LangGraph's state system.\n *\n * This reducer handles several tasks:\n * 1. Normalizes both `left` and `right` message inputs to arrays.\n * 2. Coerces any message-like objects into real `BaseMessage` instances.\n * 3. Ensures all messages have unique, stable IDs by generating missing ones.\n * 4. If a `RemoveMessage` instance is encountered in `right` with the ID `REMOVE_ALL_MESSAGES`,\n * all previous messages are discarded and only the subsequent messages in `right` are returned.\n * 5. Otherwise, merges `left` and `right` messages together following these rules:\n * - If a message in `right` shares an ID with a message in `left`:\n * - If it is a `RemoveMessage`, that message (by ID) is marked for removal.\n * - If it is a normal message, it replaces the message with the same ID from `left`.\n * - If a message in `right` **does not exist** in `left`:\n * - If it is a `RemoveMessage`, this is considered an error (cannot remove non-existent ID).\n * - Otherwise, the message is appended.\n * - Messages flagged for removal are omitted from the final output.\n *\n * @param left - The existing array (or single message) of messages from current state.\n * @param right - The new array (or single message) of messages to be applied.\n * @returns A new array of `BaseMessage` objects representing the updated state.\n *\n * @throws Error if a `RemoveMessage` is used to delete a message with an ID that does not exist in the merged list.\n *\n * @example\n * ```ts\n * const msg1 = new AIMessage(\"hello\");\n * const msg2 = new HumanMessage(\"hi\");\n * const removal = new RemoveMessage({ id: msg1.id });\n * const newState = messagesStateReducer([msg1], [msg2, removal]);\n * // newState will only contain msg2 (msg1 is removed)\n * ```\n */\nexport function messagesStateReducer(\n left: Messages,\n right: Messages\n): BaseMessage[] {\n // Ensure both left and right are arrays\n const leftArray = Array.isArray(left) ? left : [left];\n const rightArray = Array.isArray(right) ? right : [right];\n\n // Convert all input to BaseMessage instances\n const leftMessages = (leftArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n const rightMessages = (rightArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n\n // Assign missing IDs to any message in the left array\n for (const m of leftMessages) {\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n }\n\n // Assign missing IDs and check for \"remove all\" marker in right array\n let removeAllIdx: number | undefined;\n for (let i = 0; i < rightMessages.length; i += 1) {\n const m = rightMessages[i];\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n\n // If RemoveMessage with special REMOVE_ALL_MESSAGES id is found\n if (RemoveMessage.isInstance(m) && m.id === REMOVE_ALL_MESSAGES) {\n removeAllIdx = i;\n }\n }\n\n // If remove-all is present, all previous messages are wiped; return only subsequent ones\n if (removeAllIdx != null) return rightMessages.slice(removeAllIdx + 1);\n\n // Begin normal merging logic\n const merged = [...leftMessages];\n const mergedById = new Map(merged.map((m, i) => [m.id, i]));\n const idsToRemove = new Set();\n\n for (const m of rightMessages) {\n const existingIdx = mergedById.get(m.id);\n if (existingIdx !== undefined) {\n // Case: updating or removing an existing message by id\n if (RemoveMessage.isInstance(m)) {\n idsToRemove.add(m.id);\n } else {\n idsToRemove.delete(m.id);\n merged[existingIdx] = m;\n }\n } else {\n // Case: inserting a completely new message\n if (RemoveMessage.isInstance(m)) {\n throw new Error(\n `Attempting to delete a message with an ID that doesn't exist ('${m.id}')`\n );\n }\n mergedById.set(m.id, merged.length);\n merged.push(m);\n }\n }\n\n // Remove any messages whose IDs are marked for removal\n return merged.filter((m) => !idsToRemove.has(m.id));\n}\n\n/**\n * **Experimental.** Batch reducer for use with `DeltaChannel`.\n *\n * Processes all writes in one pass — dedup by ID and `RemoveMessage`\n * tombstoning — without calling {@link messagesStateReducer}.\n *\n * This reducer is batching-invariant, as required by `DeltaChannel`:\n * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.\n *\n * Raw object / string inputs are coerced to typed `BaseMessage` objects so\n * that HTTP-driven graphs work without a separate coercion step. This is not\n * full {@link messagesStateReducer} parity — `REMOVE_ALL_MESSAGES`,\n * unknown-id `RemoveMessage` errors, and missing-id UUID assignment are not\n * handled here.\n *\n * @param state - The current accumulated list of messages.\n * @param writes - Batch of writes, each a single message-like or an array.\n * @returns The new accumulated list of messages.\n *\n * @example\n * ```typescript\n * import { DeltaChannel, messagesDeltaReducer } from \"@langchain/langgraph\";\n *\n * const channel = new DeltaChannel(messagesDeltaReducer);\n * ```\n */\nexport function messagesDeltaReducer(\n state: BaseMessage[],\n writes: Messages[]\n): BaseMessage[] {\n // Each write is either an array of message-likes or a single message-like.\n // Only arrays flatten; everything else is one message.\n const flat: BaseMessageLike[] = [];\n for (const w of writes) {\n if (Array.isArray(w)) {\n flat.push(...(w as BaseMessageLike[]));\n } else {\n flat.push(w as BaseMessageLike);\n }\n }\n\n // Steady state: the reducer's own output is already typed, so skip coercion\n // on state when the first element is a BaseMessage. Only raw input (initial\n // objects, deserialized blobs) hits the slow path.\n const stateMsgs: BaseMessage[] =\n state.length > 0 && BaseMessage.isInstance(state[0])\n ? state\n : (state as BaseMessageLike[]).map(coerceMessageLikeToMessage);\n const msgs: BaseMessage[] = flat.map(coerceMessageLikeToMessage);\n\n const index = new Map<string, number>();\n for (let i = 0; i < stateMsgs.length; i += 1) {\n const mid = stateMsgs[i].id;\n if (mid != null) index.set(mid, i);\n }\n\n const result: (BaseMessage | null)[] = [...stateMsgs];\n for (const msg of msgs) {\n const mid = msg.id;\n if (mid == null) {\n result.push(msg);\n } else if (RemoveMessage.isInstance(msg)) {\n if (index.has(mid)) {\n result[index.get(mid)!] = null;\n index.delete(mid);\n }\n } else if (index.has(mid)) {\n result[index.get(mid)!] = msg;\n } else {\n index.set(mid, result.length);\n result.push(msg);\n }\n }\n return result.filter((m): m is BaseMessage => m !== null);\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CnC,SAAgB,qBACd,MACA,OACe;CAEf,MAAM,YAAY,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;CACrD,MAAM,aAAa,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;CAGzD,MAAM,eAAgB,UAAgC,IACpD,2BACD;CACD,MAAM,gBAAiB,WAAiC,IACtD,2BACD;AAGD,MAAK,MAAM,KAAK,aACd,KAAI,EAAE,OAAO,QAAQ,EAAE,OAAO,KAAA,GAAW;AACvC,IAAE,KAAK,IAAI;AACX,IAAE,UAAU,KAAK,EAAE;;CAKvB,IAAI;AACJ,MAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK,GAAG;EAChD,MAAM,IAAI,cAAc;AACxB,MAAI,EAAE,OAAO,QAAQ,EAAE,OAAO,KAAA,GAAW;AACvC,KAAE,KAAK,IAAI;AACX,KAAE,UAAU,KAAK,EAAE;;AAIrB,MAAI,cAAc,WAAW,EAAE,IAAI,EAAE,OAAA,iBACnC,gBAAe;;AAKnB,KAAI,gBAAgB,KAAM,QAAO,cAAc,MAAM,eAAe,EAAE;CAGtE,MAAM,SAAS,CAAC,GAAG,aAAa;CAChC,MAAM,aAAa,IAAI,IAAI,OAAO,KAAK,GAAG,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;CAC3D,MAAM,8BAAc,IAAI,KAAK;AAE7B,MAAK,MAAM,KAAK,eAAe;EAC7B,MAAM,cAAc,WAAW,IAAI,EAAE,GAAG;AACxC,MAAI,gBAAgB,KAAA,EAElB,KAAI,cAAc,WAAW,EAAE,CAC7B,aAAY,IAAI,EAAE,GAAG;OAChB;AACL,eAAY,OAAO,EAAE,GAAG;AACxB,UAAO,eAAe;;OAEnB;AAEL,OAAI,cAAc,WAAW,EAAE,CAC7B,OAAM,IAAI,MACR,kEAAkE,EAAE,GAAG,IACxE;AAEH,cAAW,IAAI,EAAE,IAAI,OAAO,OAAO;AACnC,UAAO,KAAK,EAAE;;;AAKlB,QAAO,OAAO,QAAQ,MAAM,CAAC,YAAY,IAAI,EAAE,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BrD,SAAgB,qBACd,OACA,QACe;CAGf,MAAM,OAA0B,EAAE;AAClC,MAAK,MAAM,KAAK,OACd,KAAI,MAAM,QAAQ,EAAE,CAClB,MAAK,KAAK,GAAI,EAAwB;KAEtC,MAAK,KAAK,EAAqB;CAOnC,MAAM,YACJ,MAAM,SAAS,KAAK,YAAY,WAAW,MAAM,GAAG,GAChD,QACC,MAA4B,IAAI,2BAA2B;CAClE,MAAM,OAAsB,KAAK,IAAI,2BAA2B;CAEhE,MAAM,wBAAQ,IAAI,KAAqB;AACvC,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK,GAAG;EAC5C,MAAM,MAAM,UAAU,GAAG;AACzB,MAAI,OAAO,KAAM,OAAM,IAAI,KAAK,EAAE;;CAGpC,MAAM,SAAiC,CAAC,GAAG,UAAU;AACrD,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAM,IAAI;AAChB,MAAI,OAAO,KACT,QAAO,KAAK,IAAI;WACP,cAAc,WAAW,IAAI;OAClC,MAAM,IAAI,IAAI,EAAE;AAClB,WAAO,MAAM,IAAI,IAAI,IAAK;AAC1B,UAAM,OAAO,IAAI;;aAEV,MAAM,IAAI,IAAI,CACvB,QAAO,MAAM,IAAI,IAAI,IAAK;OACrB;AACL,SAAM,IAAI,KAAK,OAAO,OAAO;AAC7B,UAAO,KAAK,IAAI;;;AAGpB,QAAO,OAAO,QAAQ,MAAwB,MAAM,KAAK"}
1
+ {"version":3,"file":"messages_reducer.js","names":[],"sources":["../../src/graph/messages_reducer.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n RemoveMessage,\n} from \"@langchain/core/messages\";\nimport { v4 } from \"@langchain/core/utils/uuid\";\n\n/**\n * Special value that signifies the intent to remove all previous messages in the state reducer.\n * Used as the unique identifier for a `RemoveMessage` instance which, when encountered,\n * causes all prior messages to be discarded, leaving only those following this marker.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\n/**\n * Type that represents an acceptable input for the messages state reducer.\n *\n * - Can be a single `BaseMessage` or `BaseMessageLike`.\n * - Can be an array of `BaseMessage` or `BaseMessageLike`.\n */\nexport type Messages =\n | Array<BaseMessage | BaseMessageLike>\n | BaseMessage\n | BaseMessageLike;\n\n/**\n * Reducer function for combining two sets of messages in LangGraph's state system.\n *\n * This reducer handles several tasks:\n * 1. Normalizes both `left` and `right` message inputs to arrays.\n * 2. Coerces any message-like objects into real `BaseMessage` instances.\n * 3. Ensures all messages have unique, stable IDs by generating missing ones.\n * 4. If a `RemoveMessage` instance is encountered in `right` with the ID `REMOVE_ALL_MESSAGES`,\n * all previous messages are discarded and only the subsequent messages in `right` are returned.\n * 5. Otherwise, merges `left` and `right` messages together following these rules:\n * - If a message in `right` shares an ID with a message in `left`:\n * - If it is a `RemoveMessage`, that message (by ID) is marked for removal.\n * - If it is a normal message, it replaces the message with the same ID from `left`.\n * - If a message in `right` **does not exist** in `left`:\n * - If it is a `RemoveMessage`, this is considered an error (cannot remove non-existent ID).\n * - Otherwise, the message is appended.\n * - Messages flagged for removal are omitted from the final output.\n *\n * @param left - The existing array (or single message) of messages from current state.\n * @param right - The new array (or single message) of messages to be applied.\n * @returns A new array of `BaseMessage` objects representing the updated state.\n *\n * @throws Error if a `RemoveMessage` is used to delete a message with an ID that does not exist in the merged list.\n *\n * @example\n * ```ts\n * const msg1 = new AIMessage(\"hello\");\n * const msg2 = new HumanMessage(\"hi\");\n * const removal = new RemoveMessage({ id: msg1.id });\n * const newState = messagesStateReducer([msg1], [msg2, removal]);\n * // newState will only contain msg2 (msg1 is removed)\n * ```\n */\nexport function messagesStateReducer(\n left: Messages,\n right: Messages\n): BaseMessage[] {\n // Ensure both left and right are arrays\n const leftArray = Array.isArray(left) ? left : [left];\n const rightArray = Array.isArray(right) ? right : [right];\n\n // Convert all input to BaseMessage instances\n const leftMessages = (leftArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n const rightMessages = (rightArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n\n // Assign missing IDs to any message in the left array\n for (const m of leftMessages) {\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n }\n\n // Assign missing IDs and check for \"remove all\" marker in right array\n let removeAllIdx: number | undefined;\n for (let i = 0; i < rightMessages.length; i += 1) {\n const m = rightMessages[i];\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n\n // If RemoveMessage with special REMOVE_ALL_MESSAGES id is found\n if (RemoveMessage.isInstance(m) && m.id === REMOVE_ALL_MESSAGES) {\n removeAllIdx = i;\n }\n }\n\n // If remove-all is present, all previous messages are wiped; return only subsequent ones\n if (removeAllIdx != null) return rightMessages.slice(removeAllIdx + 1);\n\n // Begin normal merging logic\n const merged = [...leftMessages];\n const mergedById = new Map(merged.map((m, i) => [m.id, i]));\n const idsToRemove = new Set();\n\n for (const m of rightMessages) {\n const existingIdx = mergedById.get(m.id);\n if (existingIdx !== undefined) {\n // Case: updating or removing an existing message by id\n if (RemoveMessage.isInstance(m)) {\n idsToRemove.add(m.id);\n } else {\n idsToRemove.delete(m.id);\n merged[existingIdx] = m;\n }\n } else {\n // Case: inserting a completely new message\n if (RemoveMessage.isInstance(m)) {\n throw new Error(\n `Attempting to delete a message with an ID that doesn't exist ('${m.id}')`\n );\n }\n mergedById.set(m.id, merged.length);\n merged.push(m);\n }\n }\n\n // Remove any messages whose IDs are marked for removal\n return merged.filter((m) => !idsToRemove.has(m.id));\n}\n\n/**\n * **Experimental.** Batch reducer for use with `DeltaChannel`.\n *\n * Processes all writes in one pass — dedup by ID and `RemoveMessage`\n * tombstoning — without calling {@link messagesStateReducer}.\n *\n * This reducer is batching-invariant, as required by `DeltaChannel`:\n * `reducer(reducer(state, xs), ys) === reducer(state, xs.concat(ys))`.\n *\n * A `RemoveMessage` carrying the {@link REMOVE_ALL_MESSAGES} sentinel id\n * clears all messages accumulated so far (prior state plus earlier writes in\n * the same batch) and keeps only the messages that follow it, mirroring\n * {@link messagesStateReducer}. Clearing happens in the same single linear\n * pass, so the batching-invariant still holds.\n *\n * Raw object / string inputs are coerced to typed `BaseMessage` objects so\n * that HTTP-driven graphs work without a separate coercion step. This is not\n * full {@link messagesStateReducer} parity — unknown-id `RemoveMessage`\n * errors and missing-id UUID assignment are not handled here.\n *\n * @param state - The current accumulated list of messages.\n * @param writes - Batch of writes, each a single message-like or an array.\n * @returns The new accumulated list of messages.\n *\n * @example\n * ```typescript\n * import { DeltaChannel, messagesDeltaReducer } from \"@langchain/langgraph\";\n *\n * const channel = new DeltaChannel(messagesDeltaReducer);\n * ```\n */\nexport function messagesDeltaReducer(\n state: BaseMessage[],\n writes: Messages[]\n): BaseMessage[] {\n // Each write is either an array of message-likes or a single message-like.\n // Only arrays flatten; everything else is one message.\n const flat: BaseMessageLike[] = [];\n for (const w of writes) {\n if (Array.isArray(w)) {\n flat.push(...(w as BaseMessageLike[]));\n } else {\n flat.push(w as BaseMessageLike);\n }\n }\n\n // Steady state: the reducer's own output is already typed, so skip coercion\n // on state when the first element is a BaseMessage. Only raw input (initial\n // objects, deserialized blobs) hits the slow path.\n const stateMsgs: BaseMessage[] =\n state.length > 0 && BaseMessage.isInstance(state[0])\n ? state\n : (state as BaseMessageLike[]).map(coerceMessageLikeToMessage);\n const msgs: BaseMessage[] = flat.map(coerceMessageLikeToMessage);\n\n const index = new Map<string, number>();\n for (let i = 0; i < stateMsgs.length; i += 1) {\n const mid = stateMsgs[i].id;\n if (mid != null) index.set(mid, i);\n }\n\n const result: (BaseMessage | null)[] = [...stateMsgs];\n for (const msg of msgs) {\n const mid = msg.id;\n if (RemoveMessage.isInstance(msg) && mid === REMOVE_ALL_MESSAGES) {\n // Discard everything accumulated so far (prior state and earlier writes\n // in this batch); only messages following the sentinel are kept. Doing\n // this inline keeps the reducer batching-invariant.\n result.length = 0;\n index.clear();\n } else if (mid == null) {\n result.push(msg);\n } else if (RemoveMessage.isInstance(msg)) {\n if (index.has(mid)) {\n result[index.get(mid)!] = null;\n index.delete(mid);\n }\n } else if (index.has(mid)) {\n result[index.get(mid)!] = msg;\n } else {\n index.set(mid, result.length);\n result.push(msg);\n }\n }\n return result.filter((m): m is BaseMessage => m !== null);\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -23,6 +23,7 @@ const require_delta = require("./channels/delta.cjs");
23
23
  const require_untracked_value = require("./channels/untracked_value.cjs");
24
24
  const require_reduced = require("./state/values/reduced.cjs");
25
25
  const require_untracked = require("./state/values/untracked.cjs");
26
+ const require_delta$1 = require("./state/values/delta.cjs");
26
27
  const require_schema = require("./state/schema.cjs");
27
28
  const require_messages_reducer = require("./graph/messages_reducer.cjs");
28
29
  const require_messages$1 = require("./state/prebuilt/messages.cjs");
@@ -70,6 +71,7 @@ exports.Command = require_constants.Command;
70
71
  exports.CommandInstance = require_constants.CommandInstance;
71
72
  exports.CompiledStateGraph = require_state.CompiledStateGraph;
72
73
  exports.DeltaChannel = require_delta.DeltaChannel;
74
+ exports.DeltaValue = require_delta$1.DeltaValue;
73
75
  exports.END = require_constants.END;
74
76
  exports.EmptyChannelError = require_errors.EmptyChannelError;
75
77
  exports.EmptyInputError = require_errors.EmptyInputError;
@@ -97,6 +99,7 @@ Object.defineProperty(exports, "MemorySaver", {
97
99
  });
98
100
  exports.MessageGraph = require_message.MessageGraph;
99
101
  exports.MessagesAnnotation = require_messages_annotation.MessagesAnnotation;
102
+ exports.MessagesDeltaValue = require_messages$1.MessagesDeltaValue;
100
103
  exports.MessagesValue = require_messages$1.MessagesValue;
101
104
  exports.MessagesZodMeta = require_messages_annotation.MessagesZodMeta;
102
105
  exports.MessagesZodState = require_messages_annotation.MessagesZodState;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["initializeAsyncLocalStorageSingleton"],"sources":["../src/index.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\nimport { initializeAsyncLocalStorageSingleton } from \"./node.js\";\n\n// Initialize global async local storage instance for tracing\ninitializeAsyncLocalStorageSingleton();\n\nexport * from \"./web.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKAA,aAAAA,sCAAsC"}
1
+ {"version":3,"file":"index.cjs","names":["initializeAsyncLocalStorageSingleton"],"sources":["../src/index.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\nimport { initializeAsyncLocalStorageSingleton } from \"./node.js\";\n\n// Initialize global async local storage instance for tracing\ninitializeAsyncLocalStorageSingleton();\n\nexport * from \"./web.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKAA,aAAAA,sCAAsC"}
package/dist/index.d.cts CHANGED
@@ -31,6 +31,7 @@ import { BaseLangGraphError, BaseLangGraphErrorFields, EmptyChannelError, EmptyI
31
31
  import { isSerializableSchema, isStandardSchema } from "./state/types.cjs";
32
32
  import { ReducedValue, ReducedValueInit } from "./state/values/reduced.cjs";
33
33
  import { UntrackedValue, UntrackedValueInit } from "./state/values/untracked.cjs";
34
+ import { DeltaValue, DeltaValueInit } from "./state/values/delta.cjs";
34
35
  import { AnyStateSchema, InferStateSchemaUpdate, InferStateSchemaValue, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition } from "./state/schema.cjs";
35
36
  import { ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ExtractStateType, ExtractUpdateType, GraphNode, GraphNodeReturnValue, GraphNodeTypes, StateDefinitionInit, StateGraphInit, StateGraphOptions, ToStateDefinition } from "./graph/types.cjs";
36
37
  import { AddNodeOptions, CompiledGraph, CompiledGraphType, Graph, NodeSpec } from "./graph/graph.cjs";
@@ -42,7 +43,7 @@ import { MessageGraph, pushMessage } from "./graph/message.cjs";
42
43
  import { EntrypointOptions, TaskOptions, entrypoint, getPreviousState, task } from "./func/index.cjs";
43
44
  import { MessagesAnnotation, MessagesZodMeta, MessagesZodState } from "./graph/messages_annotation.cjs";
44
45
  import { getJsonSchemaFromSchema, getSchemaDefaultGetter } from "./state/adapter.cjs";
45
- import { MessagesValue } from "./state/prebuilt/messages.cjs";
46
+ import { MessagesDeltaValue, MessagesValue } from "./state/prebuilt/messages.cjs";
46
47
  import { getConfig, getCurrentTaskInput, getStore, getWriter } from "./pregel/utils/config.cjs";
47
48
  import { AsyncBatchedStore, BaseCheckpointSaver, BaseStore, Checkpoint, CheckpointMetadata, CheckpointTuple, GetOperation, InMemoryStore, Item, ListNamespacesOperation, MatchCondition, MemorySaver, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PutOperation, SearchOperation, copyCheckpoint, emptyCheckpoint } from "./web.cjs";
48
- export { AddNodeOptions, AgentStatus, Annotation, AnnotationRoot, AnyStateSchema, AnyValue, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseLangGraphErrorFields, BaseStore, BinaryOperator, BinaryOperatorAggregate, COMMAND_SYMBOL, CachePolicy, ChatModelStream, ChatModelStreamImpl, Checkpoint, CheckpointMetadata, CheckpointTuple, Command, CommandInstance, CommandParams, CompiledGraph, CompiledGraphType, CompiledStateGraph, ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ConvertToProtocolEventOptions, CreateGraphRunStreamOptions, DeltaChannel, DeltaReducer, DynamicBarrierValue, END, EmptyChannelError, EmptyInputError, EntrypointOptions, EphemeralValue, StreamChannel as EventLog, ExecutionInfo, ExtractStateType, ExtractUpdateType, GetOperation, GetStateOptions, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphNode, GraphNodeReturnValue, GraphNodeTypes, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InferExtensions, InferInterruptInputType, InferInterruptResumeType, InferStateSchemaUpdate, InferStateSchemaValue, InferWriterType, Interrupt, InterruptPayload, InvalidUpdateError, Item, LangGraphRunnableConfig, LastValue, LifecycleCause, LifecycleData, LifecycleEntry, LifecycleProjection, LifecycleTransformerOptions, ListNamespacesOperation, MatchCondition, MemorySaver, MessageGraph, Messages, MessagesAnnotation, MessagesEventData, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleChannelSubscriptionOptions, MultipleSubgraphsError, NameSpacePath, NamedBarrierValue, Namespace, NamespaceMatchType, NativeStreamTransformer, NodeError, NodeInterrupt, NodePolicyOptions, NodeSpec, NodeTimeoutError, NodeType, Operation, OperationResults, Overwrite, OverwriteValue, ParentCommand, Pregel, PregelNode, PregelOptions, PregelParams, ProtocolEvent, PutOperation, REMOVE_ALL_MESSAGES, ReducedValue, ReducedValueInit, RemoteException, RetryPolicy, RunControl, Runtime, START, STREAM_EVENTS_V3_MODES, SearchOperation, Send, SendOptions, ServerInfo, SingleChannelSubscriptionOptions, SingleReducer, StateDefinition, StateDefinitionInit, StateGraph, StateGraphAddNodeOptions, StateGraphArgs, StateGraphArgsWithInputOutputSchemas, StateGraphArgsWithStateSchema, StateGraphInit, StateGraphInputError, StateGraphNodeSpec, StateGraphOptions, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition, StateSnapshot, StateType, StreamChannel, StreamEmitter, StreamMode, StreamOutputMap, StreamTransformer, SubgraphDiscoveryProjection, SubgraphDiscoveryTransformerOptions, SubgraphRunStream, TaskOptions, TimeoutPolicy, ToStateDefinition, ToolCallStatus, ToolCallStream, ToolsEventData, Topic, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, UntrackedValueInit, UpdateType, UpdatesEventData, UsageInfo, WaitForNames, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
49
+ export { AddNodeOptions, AgentStatus, Annotation, AnnotationRoot, AnyStateSchema, AnyValue, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseLangGraphErrorFields, BaseStore, BinaryOperator, BinaryOperatorAggregate, COMMAND_SYMBOL, CachePolicy, ChatModelStream, ChatModelStreamImpl, Checkpoint, CheckpointMetadata, CheckpointTuple, Command, CommandInstance, CommandParams, CompiledGraph, CompiledGraphType, CompiledStateGraph, ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ConvertToProtocolEventOptions, CreateGraphRunStreamOptions, DeltaChannel, DeltaReducer, DeltaValue, DeltaValueInit, DynamicBarrierValue, END, EmptyChannelError, EmptyInputError, EntrypointOptions, EphemeralValue, StreamChannel as EventLog, ExecutionInfo, ExtractStateType, ExtractUpdateType, GetOperation, GetStateOptions, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphNode, GraphNodeReturnValue, GraphNodeTypes, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InferExtensions, InferInterruptInputType, InferInterruptResumeType, InferStateSchemaUpdate, InferStateSchemaValue, InferWriterType, Interrupt, InterruptPayload, InvalidUpdateError, Item, LangGraphRunnableConfig, LastValue, LifecycleCause, LifecycleData, LifecycleEntry, LifecycleProjection, LifecycleTransformerOptions, ListNamespacesOperation, MatchCondition, MemorySaver, MessageGraph, Messages, MessagesAnnotation, MessagesDeltaValue, MessagesEventData, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleChannelSubscriptionOptions, MultipleSubgraphsError, NameSpacePath, NamedBarrierValue, Namespace, NamespaceMatchType, NativeStreamTransformer, NodeError, NodeInterrupt, NodePolicyOptions, NodeSpec, NodeTimeoutError, NodeType, Operation, OperationResults, Overwrite, OverwriteValue, ParentCommand, Pregel, PregelNode, PregelOptions, PregelParams, ProtocolEvent, PutOperation, REMOVE_ALL_MESSAGES, ReducedValue, ReducedValueInit, RemoteException, RetryPolicy, RunControl, Runtime, START, STREAM_EVENTS_V3_MODES, SearchOperation, Send, SendOptions, ServerInfo, SingleChannelSubscriptionOptions, SingleReducer, StateDefinition, StateDefinitionInit, StateGraph, StateGraphAddNodeOptions, StateGraphArgs, StateGraphArgsWithInputOutputSchemas, StateGraphArgsWithStateSchema, StateGraphInit, StateGraphInputError, StateGraphNodeSpec, StateGraphOptions, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition, StateSnapshot, StateType, StreamChannel, StreamEmitter, StreamMode, StreamOutputMap, StreamTransformer, SubgraphDiscoveryProjection, SubgraphDiscoveryTransformerOptions, SubgraphRunStream, TaskOptions, TimeoutPolicy, ToStateDefinition, ToolCallStatus, ToolCallStream, ToolsEventData, Topic, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, UntrackedValueInit, UpdateType, UpdatesEventData, UsageInfo, WaitForNames, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
package/dist/index.d.ts CHANGED
@@ -31,6 +31,7 @@ import { BaseLangGraphError, BaseLangGraphErrorFields, EmptyChannelError, EmptyI
31
31
  import { isSerializableSchema, isStandardSchema } from "./state/types.js";
32
32
  import { ReducedValue, ReducedValueInit } from "./state/values/reduced.js";
33
33
  import { UntrackedValue, UntrackedValueInit } from "./state/values/untracked.js";
34
+ import { DeltaValue, DeltaValueInit } from "./state/values/delta.js";
34
35
  import { AnyStateSchema, InferStateSchemaUpdate, InferStateSchemaValue, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition } from "./state/schema.js";
35
36
  import { ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ExtractStateType, ExtractUpdateType, GraphNode, GraphNodeReturnValue, GraphNodeTypes, StateDefinitionInit, StateGraphInit, StateGraphOptions, ToStateDefinition } from "./graph/types.js";
36
37
  import { AddNodeOptions, CompiledGraph, CompiledGraphType, Graph, NodeSpec } from "./graph/graph.js";
@@ -42,7 +43,7 @@ import { MessageGraph, pushMessage } from "./graph/message.js";
42
43
  import { EntrypointOptions, TaskOptions, entrypoint, getPreviousState, task } from "./func/index.js";
43
44
  import { MessagesAnnotation, MessagesZodMeta, MessagesZodState } from "./graph/messages_annotation.js";
44
45
  import { getJsonSchemaFromSchema, getSchemaDefaultGetter } from "./state/adapter.js";
45
- import { MessagesValue } from "./state/prebuilt/messages.js";
46
+ import { MessagesDeltaValue, MessagesValue } from "./state/prebuilt/messages.js";
46
47
  import { getConfig, getCurrentTaskInput, getStore, getWriter } from "./pregel/utils/config.js";
47
48
  import { AsyncBatchedStore, BaseCheckpointSaver, BaseStore, Checkpoint, CheckpointMetadata, CheckpointTuple, GetOperation, InMemoryStore, Item, ListNamespacesOperation, MatchCondition, MemorySaver, NameSpacePath, NamespaceMatchType, Operation, OperationResults, PutOperation, SearchOperation, copyCheckpoint, emptyCheckpoint } from "./web.js";
48
- export { AddNodeOptions, AgentStatus, Annotation, AnnotationRoot, AnyStateSchema, AnyValue, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseLangGraphErrorFields, BaseStore, BinaryOperator, BinaryOperatorAggregate, COMMAND_SYMBOL, CachePolicy, ChatModelStream, ChatModelStreamImpl, Checkpoint, CheckpointMetadata, CheckpointTuple, Command, CommandInstance, CommandParams, CompiledGraph, CompiledGraphType, CompiledStateGraph, ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ConvertToProtocolEventOptions, CreateGraphRunStreamOptions, DeltaChannel, DeltaReducer, DynamicBarrierValue, END, EmptyChannelError, EmptyInputError, EntrypointOptions, EphemeralValue, StreamChannel as EventLog, ExecutionInfo, ExtractStateType, ExtractUpdateType, GetOperation, GetStateOptions, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphNode, GraphNodeReturnValue, GraphNodeTypes, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InferExtensions, InferInterruptInputType, InferInterruptResumeType, InferStateSchemaUpdate, InferStateSchemaValue, InferWriterType, Interrupt, InterruptPayload, InvalidUpdateError, Item, LangGraphRunnableConfig, LastValue, LifecycleCause, LifecycleData, LifecycleEntry, LifecycleProjection, LifecycleTransformerOptions, ListNamespacesOperation, MatchCondition, MemorySaver, MessageGraph, Messages, MessagesAnnotation, MessagesEventData, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleChannelSubscriptionOptions, MultipleSubgraphsError, NameSpacePath, NamedBarrierValue, Namespace, NamespaceMatchType, NativeStreamTransformer, NodeError, NodeInterrupt, NodePolicyOptions, NodeSpec, NodeTimeoutError, NodeType, Operation, OperationResults, Overwrite, OverwriteValue, ParentCommand, Pregel, PregelNode, PregelOptions, PregelParams, ProtocolEvent, PutOperation, REMOVE_ALL_MESSAGES, ReducedValue, ReducedValueInit, RemoteException, RetryPolicy, RunControl, Runtime, START, STREAM_EVENTS_V3_MODES, SearchOperation, Send, SendOptions, ServerInfo, SingleChannelSubscriptionOptions, SingleReducer, StateDefinition, StateDefinitionInit, StateGraph, StateGraphAddNodeOptions, StateGraphArgs, StateGraphArgsWithInputOutputSchemas, StateGraphArgsWithStateSchema, StateGraphInit, StateGraphInputError, StateGraphNodeSpec, StateGraphOptions, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition, StateSnapshot, StateType, StreamChannel, StreamEmitter, StreamMode, StreamOutputMap, StreamTransformer, SubgraphDiscoveryProjection, SubgraphDiscoveryTransformerOptions, SubgraphRunStream, TaskOptions, TimeoutPolicy, ToStateDefinition, ToolCallStatus, ToolCallStream, ToolsEventData, Topic, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, UntrackedValueInit, UpdateType, UpdatesEventData, UsageInfo, WaitForNames, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
49
+ export { AddNodeOptions, AgentStatus, Annotation, AnnotationRoot, AnyStateSchema, AnyValue, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseLangGraphErrorFields, BaseStore, BinaryOperator, BinaryOperatorAggregate, COMMAND_SYMBOL, CachePolicy, ChatModelStream, ChatModelStreamImpl, Checkpoint, CheckpointMetadata, CheckpointTuple, Command, CommandInstance, CommandParams, CompiledGraph, CompiledGraphType, CompiledStateGraph, ConditionalEdgeRouter, ConditionalEdgeRouterTypes, ContextSchemaInit, ConvertToProtocolEventOptions, CreateGraphRunStreamOptions, DeltaChannel, DeltaReducer, DeltaValue, DeltaValueInit, DynamicBarrierValue, END, EmptyChannelError, EmptyInputError, EntrypointOptions, EphemeralValue, StreamChannel as EventLog, ExecutionInfo, ExtractStateType, ExtractUpdateType, GetOperation, GetStateOptions, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphNode, GraphNodeReturnValue, GraphNodeTypes, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InferExtensions, InferInterruptInputType, InferInterruptResumeType, InferStateSchemaUpdate, InferStateSchemaValue, InferWriterType, Interrupt, InterruptPayload, InvalidUpdateError, Item, LangGraphRunnableConfig, LastValue, LifecycleCause, LifecycleData, LifecycleEntry, LifecycleProjection, LifecycleTransformerOptions, ListNamespacesOperation, MatchCondition, MemorySaver, MessageGraph, Messages, MessagesAnnotation, MessagesDeltaValue, MessagesEventData, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleChannelSubscriptionOptions, MultipleSubgraphsError, NameSpacePath, NamedBarrierValue, Namespace, NamespaceMatchType, NativeStreamTransformer, NodeError, NodeInterrupt, NodePolicyOptions, NodeSpec, NodeTimeoutError, NodeType, Operation, OperationResults, Overwrite, OverwriteValue, ParentCommand, Pregel, PregelNode, PregelOptions, PregelParams, ProtocolEvent, PutOperation, REMOVE_ALL_MESSAGES, ReducedValue, ReducedValueInit, RemoteException, RetryPolicy, RunControl, Runtime, START, STREAM_EVENTS_V3_MODES, SearchOperation, Send, SendOptions, ServerInfo, SingleChannelSubscriptionOptions, SingleReducer, StateDefinition, StateDefinitionInit, StateGraph, StateGraphAddNodeOptions, StateGraphArgs, StateGraphArgsWithInputOutputSchemas, StateGraphArgsWithStateSchema, StateGraphInit, StateGraphInputError, StateGraphNodeSpec, StateGraphOptions, StateSchema, StateSchemaField, StateSchemaFieldToChannel, StateSchemaFields, StateSchemaFieldsToStateDefinition, StateSnapshot, StateType, StreamChannel, StreamEmitter, StreamMode, StreamOutputMap, StreamTransformer, SubgraphDiscoveryProjection, SubgraphDiscoveryTransformerOptions, SubgraphRunStream, TaskOptions, TimeoutPolicy, ToStateDefinition, ToolCallStatus, ToolCallStream, ToolsEventData, Topic, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, UntrackedValueInit, UpdateType, UpdatesEventData, UsageInfo, WaitForNames, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
package/dist/index.js CHANGED
@@ -23,9 +23,10 @@ import { DeltaChannel } from "./channels/delta.js";
23
23
  import { UntrackedValueChannel } from "./channels/untracked_value.js";
24
24
  import { ReducedValue } from "./state/values/reduced.js";
25
25
  import { UntrackedValue } from "./state/values/untracked.js";
26
+ import { DeltaValue } from "./state/values/delta.js";
26
27
  import { StateSchema } from "./state/schema.js";
27
28
  import { REMOVE_ALL_MESSAGES, messagesDeltaReducer, messagesStateReducer } from "./graph/messages_reducer.js";
28
- import { MessagesValue } from "./state/prebuilt/messages.js";
29
+ import { MessagesDeltaValue, MessagesValue } from "./state/prebuilt/messages.js";
29
30
  import { CompiledStateGraph, StateGraph } from "./graph/state.js";
30
31
  import { MessageGraph, pushMessage } from "./graph/message.js";
31
32
  import { entrypoint, getPreviousState, task } from "./func/index.js";
@@ -35,6 +36,6 @@ import { AsyncBatchedStore, BaseCheckpointSaver, BaseStore, InMemoryStore, Memor
35
36
  //#region src/index.ts
36
37
  initializeAsyncLocalStorageSingleton();
37
38
  //#endregion
38
- export { Annotation, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseStore, BinaryOperatorAggregate, COMMAND_SYMBOL, ChatModelStreamImpl, Command, CommandInstance, CompiledStateGraph, DeltaChannel, END, EmptyChannelError, EmptyInputError, StreamChannel as EventLog, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InvalidUpdateError, MemorySaver, MessageGraph, MessagesAnnotation, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleSubgraphsError, NodeError, NodeInterrupt, NodeTimeoutError, Overwrite, ParentCommand, REMOVE_ALL_MESSAGES, ReducedValue, RemoteException, RunControl, START, STREAM_EVENTS_V3_MODES, Send, StateGraph, StateGraphInputError, StateSchema, StreamChannel, SubgraphRunStream, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
39
+ export { Annotation, AsyncBatchedStore, BaseChannel, BaseCheckpointSaver, BaseLangGraphError, BaseStore, BinaryOperatorAggregate, COMMAND_SYMBOL, ChatModelStreamImpl, Command, CommandInstance, CompiledStateGraph, DeltaChannel, DeltaValue, END, EmptyChannelError, EmptyInputError, StreamChannel as EventLog, Graph, GraphBubbleUp, GraphDrained, GraphInterrupt, GraphRecursionError, GraphRunStream, GraphValueError, INTERRUPT, InMemoryStore, InvalidUpdateError, MemorySaver, MessageGraph, MessagesAnnotation, MessagesDeltaValue, MessagesValue, MessagesZodMeta, MessagesZodState, MultipleSubgraphsError, NodeError, NodeInterrupt, NodeTimeoutError, Overwrite, ParentCommand, REMOVE_ALL_MESSAGES, ReducedValue, RemoteException, RunControl, START, STREAM_EVENTS_V3_MODES, Send, StateGraph, StateGraphInputError, StateSchema, StreamChannel, SubgraphRunStream, UnreachableNodeError, UntrackedValue, UntrackedValueChannel, messagesStateReducer as addMessages, convertToProtocolEvent, copyCheckpoint, createGraphRunStream, createLifecycleTransformer, createMessagesTransformer, createSubgraphDiscoveryTransformer, createValuesTransformer, emptyCheckpoint, entrypoint, filterLifecycleEntries, filterSubgraphHandles, getConfig, getCurrentTaskInput, getJsonSchemaFromSchema, getPreviousState, getSchemaDefaultGetter, getStore, getSubgraphsSeenSet, getWriter, interrupt, isCheckpointEnvelope, isCommand, isGraphBubbleUp, isGraphDrained, isGraphInterrupt, isInterrupted, isNativeTransformer, isNodeError, isNodeTimeoutError, isParentCommand, isSerializableSchema, isStandardSchema, messagesDeltaReducer, messagesStateReducer, pushMessage, task, writer };
39
40
 
40
41
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\nimport { initializeAsyncLocalStorageSingleton } from \"./node.js\";\n\n// Initialize global async local storage instance for tracing\ninitializeAsyncLocalStorageSingleton();\n\nexport * from \"./web.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sCAAsC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\nimport { initializeAsyncLocalStorageSingleton } from \"./node.js\";\n\n// Initialize global async local storage instance for tracing\ninitializeAsyncLocalStorageSingleton();\n\nexport * from \"./web.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,sCAAsC"}
@@ -118,9 +118,26 @@ function _applyWrites(checkpoint, channels, tasks, getNextVersion, triggerToNode
118
118
  }
119
119
  }
120
120
  const pendingWritesByChannel = {};
121
- for (const task of tasks) for (const [chan, val] of task.writes) if (IGNORE.has(chan)) {} else if (chan in onlyChannels) {
122
- pendingWritesByChannel[chan] ??= [];
123
- pendingWritesByChannel[chan].push(val);
121
+ const pendingWriteTaskIdsByChannel = {};
122
+ for (const task of tasks) {
123
+ const taskId = task.id ?? "";
124
+ for (const [chan, val] of task.writes) if (IGNORE.has(chan)) {} else if (chan in onlyChannels) {
125
+ pendingWritesByChannel[chan] ??= [];
126
+ pendingWritesByChannel[chan].push(val);
127
+ pendingWriteTaskIdsByChannel[chan] ??= [];
128
+ pendingWriteTaskIdsByChannel[chan].push(taskId);
129
+ }
130
+ }
131
+ for (const [chan, vals] of Object.entries(pendingWritesByChannel)) {
132
+ if (vals.length < 2) continue;
133
+ if (onlyChannels[chan]?.lc_graph_name !== "DeltaChannel") continue;
134
+ const taskIds = pendingWriteTaskIdsByChannel[chan];
135
+ const paired = vals.map((val, i) => ({
136
+ val,
137
+ taskId: taskIds[i]
138
+ }));
139
+ paired.sort((a, b) => a.taskId < b.taskId ? -1 : a.taskId > b.taskId ? 1 : 0);
140
+ pendingWritesByChannel[chan] = paired.map((p) => p.val);
124
141
  }
125
142
  if (maxVersion != null && getNextVersion != null) maxVersion = usedNewVersion ? getNextVersion(maxVersion) : maxVersion;
126
143
  const updatedChannels = /* @__PURE__ */ new Set();