Skip to content

Conversation

@christian-bromann
Copy link
Member

Port of langchain-ai/langchain#34609

Problem

When using agents with tools (like file reading, web search, etc.), the conversation looks like this:

[User]     "Read these 10 files and summarize them"
[AI]       "I'll read all 10 files" + [tool_call: read_file x 10]
[Tool]     "Contents of file1.txt..."
[Tool]     "Contents of file2.txt..."
...

When the conversation gets too long, SummarizationMiddleware kicks in to compress older messages. The problem was:

If you asked to keep the last 6 messages, you'd get:

[Summary]  "Here's what happened before..."
[Tool]     "Contents of file5.txt..."
[Tool]     "Contents of file6.txt..."
...

The AI's original request to read the files ([AI] message with tool_calls) was summarized away, but the tool responses remained. This caused the error:

Error code: 400 - "No tool call found for function call output with call_id..."

Many APIs require that every tool response has a matching tool request. Without the AI message, the tool responses are "orphaned."

The Fix

Now when the cutoff lands on tool messages, we move backward to include the AI message that requested those tools:

[Summary]  "Here's what happened before..."
[AI]       "I'll read all 10 files" + [tool_call: read_file x 10]
[Tool]     "Contents of file1.txt..."
[Tool]     "Contents of file2.txt..."
... (all tool responses preserved with their AIMessage)

The AI message is preserved along with its tool responses, keeping them paired together.

Changes

  • Added findSafeCutoffPoint() function that searches backward for matching AIMessage when cutoff lands on ToolMessage
  • Updated findTokenBasedCutoff() and findSafeCutoff() to use the new function
  • Added tests for AI/Tool pair preservation including parallel tool calls scenario

Port of langchain-ai/langchain#34609

When SummarizationMiddleware triggers and the cutoff lands on a ToolMessage,
the middleware now searches backward for the AIMessage with matching tool_calls
and includes it in the preserved messages. This prevents "orphaned" tool
responses that cause API errors like:

  "No tool call found for function call output with call_id..."
@changeset-bot
Copy link

changeset-bot bot commented Jan 6, 2026

🦋 Changeset detected

Latest commit: 116f10b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
langchain Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the ready label Jan 6, 2026
@christian-bromann christian-bromann merged commit f697451 into main Jan 6, 2026
34 checks passed
@christian-bromann christian-bromann deleted the cb/summarization-cut-off branch January 6, 2026 01:14
@github-actions github-actions bot mentioned this pull request Jan 6, 2026
FilipZmijewski pushed a commit to FilipZmijewski/langchainjs that referenced this pull request Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants