add main.py
This commit is contained in:
@@ -1,61 +1,49 @@
|
|||||||
import questionary
|
import sys
|
||||||
from langgraph.graph import StateGraph, START
|
from langgraph.graph import StateGraph, START
|
||||||
from langgraph.types import interrupt, Command
|
from langgraph.types import interrupt, Command
|
||||||
from langgraph.checkpoint.memory import InMemorySaver
|
from langgraph.checkpoint.memory import InMemorySaver
|
||||||
from typing import TypedDict, Annotated
|
from typing import TypedDict, Annotated
|
||||||
|
from langgraph.graph.message import add_messages
|
||||||
|
import questionary
|
||||||
|
|
||||||
# State definition
|
|
||||||
class GraphState(TypedDict):
|
class GraphState(TypedDict):
|
||||||
human_value: Annotated[str | None, "value chosen by user"]
|
messages: Annotated[list, add_messages]
|
||||||
foo: Annotated[str, "initial data placeholder"]
|
human_value: str | None
|
||||||
|
|
||||||
# Node that triggers interrupt
|
async def interrupt_node(state: GraphState) -> GraphState:
|
||||||
|
# Trigger interrupt asking user to confirm
|
||||||
def interrupt_node(state: GraphState) -> GraphState:
|
|
||||||
# Trigger interrupt with structured payload
|
|
||||||
payload = {
|
payload = {
|
||||||
"type": "confirm",
|
"type": "confirm",
|
||||||
"question": "Уверены, что хотите продолжить?",
|
"question": "Do you want to continue?",
|
||||||
"allow_responds": ["approve", "reject"],
|
"options": ["yes", "no"],
|
||||||
}
|
}
|
||||||
# Call interrupt; execution pauses until resumed
|
# interrupt returns None, graph pauses
|
||||||
interrupt(payload)
|
interrupt(payload)
|
||||||
# After resume, payload will contain 'answer'
|
# After resume, payload will have 'answer'
|
||||||
# The node receives the resumed payload as its return value
|
answer = state.get("human_value")
|
||||||
# We store the answer in state
|
return {"messages": state["messages"], "human_value": answer}
|
||||||
state["human_value"] = payload.get("answer")
|
|
||||||
return state
|
|
||||||
|
|
||||||
# Build graph
|
|
||||||
builder = StateGraph(GraphState)
|
builder = StateGraph(GraphState)
|
||||||
builder.add_node("interrupt_node", interrupt_node)
|
builder.add_node("interrupt_node", interrupt_node)
|
||||||
builder.add_edge(START, "interrupt_node")
|
builder.add_edge(START, "interrupt_node")
|
||||||
builder.add_edge("interrupt_node", END)
|
builder.add_edge("interrupt_node", START)
|
||||||
|
|
||||||
# Compile with checkpoint
|
|
||||||
graph = builder.compile(checkpointer=InMemorySaver())
|
graph = builder.compile(checkpointer=InMemorySaver())
|
||||||
|
|
||||||
# Run graph with stream and handle interrupt
|
async def main():
|
||||||
config = {"configurable": {"thread_id": "demo"}}
|
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
|
if __name__ == "__main__":
|
||||||
stream = graph.stream({}, config)
|
import asyncio
|
||||||
for chunk in stream:
|
asyncio.run(main())
|
||||||
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)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user