@ai-sdk/langchain 2.0.228 → 2.0.230

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/src/adapter.ts CHANGED
@@ -153,8 +153,41 @@ function processStreamEventsEvent(
153
153
  switch (event.event) {
154
154
  case 'on_chat_model_start': {
155
155
  /**
156
- * Handle model start - capture message metadata if available
157
- * run_id is at event level in v2, but check data for backwards compatibility
156
+ * End the previous model turn's reasoning stream before a new LLM invocation.
157
+ * Without this, reasoning-delta chunks from the next turn could attach to the
158
+ * wrong reasoning part in the UI message stream.
159
+ */
160
+ if (state.reasoningStarted) {
161
+ controller.enqueue({
162
+ type: 'reasoning-end',
163
+ id:
164
+ state.reasoningMessageId != null
165
+ ? state.reasoningMessageId
166
+ : state.messageId,
167
+ });
168
+ state.reasoningStarted = false;
169
+ state.reasoningMessageId = null;
170
+ }
171
+
172
+ /**
173
+ * End the previous model turn's text stream before a new LLM invocation.
174
+ * The streamEvents adapter otherwise leaves `textStarted` true, so all later
175
+ * text-delta chunks append to the first text part — tools still grow the parts
176
+ * array, which breaks chronological order in the assistant message.
177
+ */
178
+ if (state.textStarted) {
179
+ controller.enqueue({
180
+ type: 'text-end',
181
+ id:
182
+ state.textMessageId != null ? state.textMessageId : state.messageId,
183
+ });
184
+ state.textStarted = false;
185
+ state.textMessageId = null;
186
+ }
187
+
188
+ /**
189
+ * Handle model start — capture message metadata if available.
190
+ * `run_id` is on the event in streamEvents v2; fall back to `data` for compatibility.
158
191
  */
159
192
  const runId = event.run_id || (event.data.run_id as string | undefined);
160
193
  if (runId) {
package/src/utils.ts CHANGED
@@ -1698,6 +1698,11 @@ export function processLangGraphEvent(
1698
1698
  input: toolCall.args,
1699
1699
  dynamic: true,
1700
1700
  });
1701
+ } else if (toolCall.id && emittedToolCalls.has(toolCall.id)) {
1702
+ // Register key mapping for tool calls already emitted via messages mode
1703
+ // so that __interrupt__ handling can match them by key
1704
+ const toolCallKey = `${toolCall.name}:${JSON.stringify(toolCall.args)}`;
1705
+ emittedToolCallsByKey.set(toolCallKey, toolCall.id);
1701
1706
  }
1702
1707
  }
1703
1708
  }