feat(langchain): add respond decision to HITL middleware#37095
Merged
Sydney Runkle (sydney-runkle) merged 1 commit intoApr 30, 2026
Conversation
Extends `HumanInTheLoopMiddleware` with a new `respond` decision type for "ask user" style tools whose real implementation is the human's response. The interrupt is raised with the tool call as usual; the resume payload becomes the body of a synthetic `ToolMessage` with `status="success"`, and the tool itself is not executed. This complements `reject` (synthetic `ToolMessage` with `status="error"`) by providing the symmetric success path: a reviewer can answer on the tool's behalf without invoking it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merging this PR will degrade performance by 99.6%
Performance Changes
Comparing Footnotes
|
Eugene Yurtsev (eyurtsev)
approved these changes
Apr 30, 2026
Hunter Lovell (hntrl)
approved these changes
Apr 30, 2026
Sydney Runkle (sydney-runkle)
added a commit
that referenced
this pull request
Apr 30, 2026
Bumps `langchain` from 1.2.16 → 1.2.17. Picks up: - `respond` decision added to HITL middleware (#37095) > This PR was opened with AI-agent assistance.
Sydney Runkle (sydney-runkle)
added a commit
to langchain-ai/docs
that referenced
this pull request
May 1, 2026
updating based on langchain-ai/langchain#37095
Mason Daugherty (mdrxy)
added a commit
to langchain-ai/deepagents
that referenced
this pull request
May 6, 2026
… decision (#3200) The HITL trio (`test_hitl_agent`, `test_subagent_with_hitl`, `test_subagent_with_custom_interrupt_on`) had been failing on every model eval, because the `review_configs` assertions pinned the pre-`respond` contract. Upstream [langchain-ai/langchain#37095](langchain-ai/langchain#37095) (in `langchain` 1.2.x) added a fourth `respond` decision and now resolves `interrupt_on[tool] = True` to `["approve", "edit", "reject", "respond"]`.
Mason Daugherty (mdrxy)
added a commit
to langchain-ai/deepagents
that referenced
this pull request
May 6, 2026
The three HITL tests in `libs/evals/tests/evals/test_hitl.py` were failing for every model the eval matrix ran against because they assert SDK structural state (interrupt payload shape, `allowed_decisions` contents) — not model behavior. When [langchain-ai/langchain#37095](langchain-ai/langchain#37095) added a fourth `respond` decision in 1.2.x, the auto-failure-analyzer attributed the breakage to model capability gaps. Two-pronged fix: move them where they belong, and lock CI dep resolution so the next surprise upstream change is a deliberate commit instead of a fresh resolve.
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.
Extends
HumanInTheLoopMiddlewarewith a newresponddecision type for "ask user" style tools — tools whose real implementation is the human's response. The interrupt is raised with the tool call as usual; the resume payload becomes the body of a syntheticToolMessagewithstatus="success", and the tool itself is not executed.This complements
reject(which produces a syntheticToolMessagewithstatus="error") by enabling the symmetric success path: a reviewer can answer on the tool's behalf without invoking it.Changes
RespondDecisionTypedDictwith a requiredmessage: strfield; added to theDecisionunion."respond"added to theDecisionTypeliteral._process_decisionhandles"respond"by emitting aToolMessagewithstatus="success"and preserving the original tool call on theAIMessageso provider-required tool-call/tool-message pairing is maintained.Trueshortcut ininterrupt_onnow expands to["approve", "edit", "reject", "respond"], so existing callers that opted into "all decisions" pick up the new capability without code changes. Therejectdecision already permits a reviewer to inject arbitraryToolMessagecontent, sorespondextends the same trust model — not a new capability class.Example
Implementation drafted with AI-agent assistance.