From 333c1d588132355a9e7bfdd7bbd6db9ada7c6113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D1=80=D0=B0=D1=82=20=D0=A4=D0=B0=D0=B7=D1=8B?= =?UTF-8?q?=D0=BB=D0=BE=D0=B2?= Date: Tue, 12 May 2026 22:08:06 +0000 Subject: [PATCH] add file --- main.py | 54 +++++++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/main.py b/main.py index 84710b6..b83e703 100644 --- a/main.py +++ b/main.py @@ -1,27 +1,25 @@ import questionary from langgraph.graph import StateGraph, START -from langgraph.constants import interrupt -from langgraph.types import Command +from langgraph.types import interrupt, Command from langgraph.checkpoint.memory import InMemorySaver -from typing import TypedDict, List, Dict +from typing import TypedDict, List, Dict, Any class GraphState(TypedDict): human_value: str | None - foo: str | None + foo: str # Node that triggers interrupt - -def interrupt_node(state: GraphState) -> GraphState: +async def interrupt_node(state: GraphState) -> GraphState: # Trigger interrupt with structured payload payload = { "type": "confirm", "question": "Уверены, что хотите продолжить?", "allow_responds": ["approve", "reject"], } - # interrupt returns None, execution pauses until resume + # interrupt returns None; graph pauses until resumed interrupt(payload) - # After resume, the same payload will be passed back via state - # We expect the resume payload to contain 'answer' + # After resume, state will contain the payload with added answer + # Extract answer and store in state answer = state.get("answer") state["human_value"] = answer return state @@ -30,38 +28,32 @@ def interrupt_node(state: GraphState) -> GraphState: builder = StateGraph(GraphState) builder.add_node("interrupt_node", interrupt_node) builder.set_entry_point("interrupt_node") +builder.add_edge(START, "interrupt_node") +# No further nodes; graph ends after node builder.set_finish_point("interrupt_node") -# Use InMemorySaver for checkpointing + +# Compile with checkpoint checkpoint = InMemorySaver() graph = builder.compile(checkpointer=checkpoint) # Run graph with interrupt handling config = {"configurable": {"thread_id": "thread-1"}} -# Initial state -state: GraphState = {"human_value": None, "foo": None} +stream = graph.stream({}, config) -# Start streaming -stream = graph.stream(state, config) for chunk in stream: if "__interrupt__" in chunk: - # Extract payload - payload = chunk["__interrupt__"][0].value + # Get the interrupt payload + interrupt_payload = chunk["__interrupt__"][0].value # Show question to user answer = questionary.select( - payload["question"], - choices=payload["allow_responds"], + interrupt_payload["question"], + choices=interrupt_payload["allow_responds"], ).ask() # Add answer to payload and resume - payload["answer"] = answer - # Resume graph - stream = graph.stream(Command(resume=payload), config) - # Continue processing resumed stream - for subchunk in stream: - if "__interrupt__" in subchunk: - # Should not happen in this simple example - continue - print(subchunk) - else: - print(chunk) - -print("Final state:", state) + interrupt_payload["answer"] = answer + stream = graph.stream(Command(resume=interrupt_payload), config) + continue + # Print final state when finished + if "node" in chunk: + print("Final state:", chunk["node"]["human_value"]) + break