From 9467a0e2bb5cf6ae196af286c589e31aa004ce79 Mon Sep 17 00:00:00 2001 From: Caspar Broekhuizen Date: Sun, 14 Sep 2025 19:11:19 -0700 Subject: [PATCH] =?UTF-8?q?revert(langgraph):=20restore=20logic=20to=20sur?= =?UTF-8?q?face=20interrupts=20for=20stream=5Fmod=E2=80=A6=20(#6141)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Description Revert change in #5201 that prevented the surfacing of interrupts when `stream_mode="values"`. [Comment highlighting affected lines](https://github.com/langchain-ai/langgraph/pull/5201#discussion_r2344884841) Resolves #5409 ### Test Add test to verify interrupts are properly surfaced when `stream_mode="values"` (`test_interrupt_stream_mode_values`) --- libs/langgraph/langgraph/pregel/_loop.py | 6 +++++- libs/langgraph/tests/test_pregel.py | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/libs/langgraph/langgraph/pregel/_loop.py b/libs/langgraph/langgraph/pregel/_loop.py index 9c6c44d20..3583b6ff1 100644 --- a/libs/langgraph/langgraph/pregel/_loop.py +++ b/libs/langgraph/langgraph/pregel/_loop.py @@ -904,7 +904,11 @@ class PregelLoop: ) } ] - self._emit("updates", lambda: iter(interrupts)) + stream_modes = self.stream.modes if self.stream else [] + if "updates" in stream_modes: + self._emit("updates", lambda: iter(interrupts)) + elif "values" in stream_modes: + self._emit("values", lambda: iter(interrupts)) elif writes[0][0] != ERROR: self._emit( "updates", diff --git a/libs/langgraph/tests/test_pregel.py b/libs/langgraph/tests/test_pregel.py index c01163794..b9d2b641c 100644 --- a/libs/langgraph/tests/test_pregel.py +++ b/libs/langgraph/tests/test_pregel.py @@ -8430,3 +8430,22 @@ def test_null_resume_disallowed_with_multiple_interrupts( "text_1": "resume for prompt: original text 1", "text_2": "resume for prompt: original text 2", } + + +def test_interrupt_stream_mode_values(): + """Test that interrupts are surfaced when steam_mode='values'""" + + class State(TypedDict): + human_input: str + + def human_input_node(state: State) -> Command: + human_input = interrupt("interrupt") + return Command(update={"human_input": human_input}) + + builder = StateGraph(State) + builder.add_node(human_input_node) + builder.add_edge(START, "human_input_node") + app = builder.compile() + + result = [*app.stream(State(), stream_mode="values")] + assert "__interrupt__" in result[-1]