prebuilt: add filter_orphaned_reasoning_messages pre_model_hook#7229
Open
Alan Andrade (alan-andrade) wants to merge 1 commit intolangchain-ai:mainfrom
Open
Conversation
Add a public `filter_orphaned_reasoning_messages` function usable as a `pre_model_hook` in `create_react_agent`. When a client aborts a streaming response mid-flight, LangGraph may persist an AIMessage whose content is exclusively reasoning blocks with no following text or tool-call output. Replaying that orphaned message on the next turn causes a provider error (e.g. OpenAI Responses API: "Item 'rs_...' of type 'reasoning' was provided without its required following item."). The function scans `state["messages"]` for such orphaned messages and returns `RemoveMessage` entries to delete them before the model is called. If no orphaned messages are found it returns `None`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
|
This PR has been automatically closed because it does not link to an approved issue. All external contributions must reference an approved issue or discussion. Please:
Maintainers: reopen this PR or remove the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
When a client aborts a streaming response mid-flight, LangGraph may persist an
AIMessagewhose content consists exclusively oftype="reasoning"blocks with no accompanying text or tool-call output. On the next conversation turn, replaying that orphaned message causes a provider error:This is a gap in the existing
_validate_chat_historylogic, which only checks for orphaned tool calls, not orphaned reasoning blocks.What
Adds a public
filter_orphaned_reasoning_messagesfunction tolanggraph.prebuiltthat is designed to be passed directly as apre_model_hooktocreate_react_agent:The function:
state["messages"]forAIMessages whose content is a non-empty list of onlytype="reasoning"blocks and that carry notool_calls{"messages": [RemoveMessage(id=...), ...]}to strip them before the model callNone(no-op) when no orphaned messages are presentidrather than raising15 unit tests cover the full edge-case surface: empty content, mixed reasoning+text (complete turns, not orphaned), messages with
tool_calls, multiple orphans, idempotency, and the no-id edge case.Notes
This pattern was first implemented in production at dbt Labs to handle stream-abort scenarios with the OpenAI Responses API (
o3,o4-mini). It sits alongside the existing_validate_chat_historyorphaned-tool-call check and is non-overlapping with it by construction —_is_reasoning_onlyreturnsFalsefor any message carryingtool_calls.Drafted by Claude Sonnet 4.6 under the direction of Alan Andrade (@alan-andrade)