add main.py

This commit is contained in:
2026-05-25 22:27:44 +00:00
parent 3acb7e5337
commit 962e965d81
+31 -43
View File
@@ -1,61 +1,49 @@
import questionary
import sys
from langgraph.graph import StateGraph, START
from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import InMemorySaver
from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages
import questionary
# State definition
class GraphState(TypedDict):
human_value: Annotated[str | None, "value chosen by user"]
foo: Annotated[str, "initial data placeholder"]
messages: Annotated[list, add_messages]
human_value: str | None
# Node that triggers interrupt
def interrupt_node(state: GraphState) -> GraphState:
# Trigger interrupt with structured payload
async def interrupt_node(state: GraphState) -> GraphState:
# Trigger interrupt asking user to confirm
payload = {
"type": "confirm",
"question": "Уверены, что хотите продолжить?",
"allow_responds": ["approve", "reject"],
"question": "Do you want to continue?",
"options": ["yes", "no"],
}
# Call interrupt; execution pauses until resumed
# interrupt returns None, graph pauses
interrupt(payload)
# After resume, payload will contain 'answer'
# The node receives the resumed payload as its return value
# We store the answer in state
state["human_value"] = payload.get("answer")
return state
# After resume, payload will have 'answer'
answer = state.get("human_value")
return {"messages": state["messages"], "human_value": answer}
# Build graph
builder = StateGraph(GraphState)
builder.add_node("interrupt_node", interrupt_node)
builder.add_edge(START, "interrupt_node")
builder.add_edge("interrupt_node", END)
# Compile with checkpoint
builder.add_edge("interrupt_node", START)
graph = builder.compile(checkpointer=InMemorySaver())
# Run graph with stream and handle interrupt
config = {"configurable": {"thread_id": "demo"}}
async def main():
config = {"configurable": {"thread_id": "session-1"}}
# Start stream
async for chunk in graph.stream({"messages": [], "human_value": None}, config):
if "__interrupt__" in chunk:
payload = chunk["__interrupt__"][0].value
answer = questionary.select(payload["question"], choices=payload["options"]).ask()
# resume with answer
payload["answer"] = answer
# store answer in state
chunk["human_value"] = answer
await graph.stream(Command(resume=payload), config)
else:
print(chunk)
# First run: will pause at interrupt
stream = graph.stream({}, config)
for chunk in stream:
if "__interrupt__" in chunk:
# Extract payload
payload = chunk["__interrupt__"][0].value
# Show question and get answer
answer = questionary.select(
payload["question"],
choices=payload["allow_responds"],
).ask()
# Add answer to payload
payload["answer"] = answer
# Resume graph
stream = graph.stream(Command(resume=payload), config)
continue
# Print normal output
print(chunk)
# After stream ends, print final state
print("Final state:", stream.final_state)
if __name__ == "__main__":
import asyncio
asyncio.run(main())