add file
This commit is contained in:
@@ -1,57 +1,66 @@
|
|||||||
import questionary
|
import sys
|
||||||
from langgraph.graph import StateGraph, START
|
from typing import TypedDict, List, Dict, Any
|
||||||
from langgraph.types import interrupt, Command
|
|
||||||
from langgraph.checkpoint.memory import InMemorySaver
|
|
||||||
from typing import TypedDict, List
|
|
||||||
|
|
||||||
class GraphState(TypedDict):
|
from langgraph.graph import StateGraph, START
|
||||||
|
from langgraph.constants import interrupt
|
||||||
|
from langgraph.types import Command
|
||||||
|
from langgraph.checkpoint.memory import InMemorySaver
|
||||||
|
import questionary
|
||||||
|
|
||||||
|
# Define state
|
||||||
|
class State(TypedDict):
|
||||||
human_value: str | None
|
human_value: str | None
|
||||||
foo: str | None
|
foo: str | None
|
||||||
|
|
||||||
# Node that triggers interrupt
|
# Node that triggers interrupt
|
||||||
|
def interrupt_node(state: State) -> State:
|
||||||
def interrupt_node(state: GraphState) -> GraphState:
|
# Trigger interrupt with question and options
|
||||||
# Trigger interrupt with payload
|
interrupt_payload = {
|
||||||
payload = {
|
|
||||||
"type": "confirm",
|
"type": "confirm",
|
||||||
"question": "Уверены, что хотите продолжить?",
|
"question": "Уверены, что хотите продолжить?",
|
||||||
"allow_responds": ["approve", "reject"],
|
"allow_responds": ["approve", "reject"],
|
||||||
}
|
}
|
||||||
# interrupt returns None; graph pauses until resumed
|
# Raise interrupt; graph will pause until resumed
|
||||||
interrupt(payload)
|
interrupt(interrupt_payload)
|
||||||
# After resume, state will contain the answer in payload['answer']
|
# After resume, the payload will be merged into state via resume
|
||||||
answer = state.get("answer")
|
# We expect state to contain 'human_value' set by resume
|
||||||
state["human_value"] = answer
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
builder = StateGraph(GraphState)
|
# Build graph
|
||||||
builder.add_node("interrupt", interrupt_node)
|
graph = StateGraph(State)
|
||||||
builder.set_entry_point("interrupt")
|
graph.add_node("interrupt", interrupt_node)
|
||||||
builder.add_edge(START, "interrupt")
|
graph.set_entry_point(START)
|
||||||
builder.add_edge("interrupt", "interrupt") # loop to finish
|
graph.add_edge(START, "interrupt")
|
||||||
graph = builder.compile(checkpointer=InMemorySaver())
|
# No further nodes; graph ends after interrupt node
|
||||||
|
graph.set_finish_point("interrupt")
|
||||||
|
|
||||||
|
# Compile with checkpoint
|
||||||
|
checkpoint = InMemorySaver()
|
||||||
|
compiled = graph.compile(checkpointer=checkpoint)
|
||||||
|
|
||||||
# Run graph with interrupt handling
|
# Run graph with interrupt handling
|
||||||
config = {"configurable": {"thread_id": "demo"}}
|
if __name__ == "__main__":
|
||||||
|
thread_id = "demo_thread"
|
||||||
# Initial state
|
config = {"configurable": {"thread_id": thread_id}}
|
||||||
state: GraphState = {"human_value": None, "foo": None}
|
# Start stream
|
||||||
|
stream = compiled.stream({}, config)
|
||||||
# Stream execution
|
for chunk in stream:
|
||||||
for chunk in graph.stream(state, config):
|
|
||||||
if "__interrupt__" in chunk:
|
if "__interrupt__" in chunk:
|
||||||
# Extract payload
|
# Extract interrupt payload
|
||||||
payload = chunk["__interrupt__"][0].value
|
interrupt_obj = chunk["__interrupt__"][0]
|
||||||
# Show question
|
payload = interrupt_obj.value
|
||||||
|
# Show question to user
|
||||||
answer = questionary.select(
|
answer = questionary.select(
|
||||||
payload["question"],
|
payload["question"],
|
||||||
choices=payload["allow_responds"],
|
choices=payload["allow_responds"],
|
||||||
).ask()
|
).ask()
|
||||||
# Resume with answer
|
# Resume with answer
|
||||||
payload["answer"] = answer
|
resume_payload = {"human_value": answer}
|
||||||
resume = Command(resume=payload)
|
stream = compiled.stream(Command(resume=resume_payload), config)
|
||||||
for _ in graph.stream(resume, config):
|
for subchunk in stream:
|
||||||
pass
|
if "human_value" in subchunk:
|
||||||
|
print("\nFinal state:", subchunk)
|
||||||
|
sys.exit(0)
|
||||||
else:
|
else:
|
||||||
# Final state output
|
# Normal output (none expected here)
|
||||||
print("Final state:", chunk)
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user