feat: solution for unknown
This commit is contained in:
@@ -1,67 +1,57 @@
|
|||||||
from typing import TypedDict, Dict, Any
|
from langchain_openai import ChatOpenAI
|
||||||
|
from pydantic import SecretStr
|
||||||
from langgraph.graph import StateGraph, START, END
|
from langgraph.graph import StateGraph, START, END, interrupt
|
||||||
from langgraph.checkpoint.memory import InMemorySaver
|
from langgraph.checkpoint.memory import InMemorySaver
|
||||||
|
from typing import TypedDict
|
||||||
|
|
||||||
|
# LLM placeholder
|
||||||
|
llm = ChatOpenAI(
|
||||||
|
model="openai/gpt-oss-20b",
|
||||||
|
base_url='https://platform.brojs.ru/jrnl-bh/api/inference/v1',
|
||||||
|
api_key=SecretStr("jrnl_30283ab953615cbb6846ff9940a1eedce0b76d7b2f59a2394f29e74643e6a90d"),
|
||||||
|
temperature=0.7,
|
||||||
|
)
|
||||||
|
|
||||||
|
# State definition
|
||||||
class GraphState(TypedDict):
|
class GraphState(TypedDict):
|
||||||
human_value: str | None
|
human_value: str | None
|
||||||
__interrupt__: dict[str, Any] | None # for interrupt payload
|
|
||||||
__resume__: str | None # for resume payload
|
|
||||||
|
|
||||||
|
# Node that triggers an interrupt with a question and options
|
||||||
def interrupt_node(state: GraphState) -> Dict[str, Any]:
|
def ask_node(state: GraphState) -> dict:
|
||||||
"""Trigger an interrupt asking the user to choose a value."""
|
return interrupt(
|
||||||
return {
|
{
|
||||||
"__interrupt__": {
|
|
||||||
"type": "question",
|
"type": "question",
|
||||||
"question": "Choose a value:",
|
"question": "Выберите вариант:",
|
||||||
"options": ["Option A", "Option B", "Option C"],
|
"options": ["Опция 1", "Опция 2", "Опция 3"],
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build the graph
|
||||||
def resume_node(state: GraphState) -> Dict[str, Any]:
|
|
||||||
"""Store the user's choice and finish."""
|
|
||||||
# The chosen option is passed via the __resume__ key
|
|
||||||
if state.get("__resume__") is not None:
|
|
||||||
state["human_value"] = state["__resume__"]
|
|
||||||
return {"__end__": True}
|
|
||||||
|
|
||||||
|
|
||||||
builder = StateGraph(GraphState)
|
builder = StateGraph(GraphState)
|
||||||
builder.add_node("interrupt", interrupt_node)
|
builder.add_node("ask", ask_node)
|
||||||
builder.add_node("resume", resume_node)
|
builder.set_entry_point(START)
|
||||||
|
builder.add_edge(START, "ask")
|
||||||
# The graph starts with the interrupt node
|
builder.add_edge("ask", END)
|
||||||
builder.set_entry_point("interrupt")
|
|
||||||
|
|
||||||
# After a successful resume, we end the graph
|
|
||||||
builder.add_edge(START, "interrupt")
|
|
||||||
builder.add_conditional_edges(
|
|
||||||
"interrupt",
|
|
||||||
lambda x: "__interrupt__" in x,
|
|
||||||
{"__interrupt__": "resume"},
|
|
||||||
)
|
|
||||||
builder.add_edge("resume", END)
|
|
||||||
|
|
||||||
graph = builder.compile(checkpointer=InMemorySaver())
|
graph = builder.compile(checkpointer=InMemorySaver())
|
||||||
|
|
||||||
# Run the graph and handle interrupts
|
# Main loop handling interrupts
|
||||||
state: GraphState = {"human_value": None, "__interrupt__": None, "__resume__": None}
|
state: GraphState = {"human_value": None}
|
||||||
while True:
|
while True:
|
||||||
result = graph.invoke(state)
|
result = graph.invoke(state)
|
||||||
if "__interrupt__" in result and result["__interrupt__"] is not None:
|
if "__interrupt__" in result:
|
||||||
interrupt_info = result["__interrupt__"]
|
interrupt_data = result["__interrupt__"]
|
||||||
print(interrupt_info["question"])
|
print(interrupt_data["question"])
|
||||||
for idx, opt in enumerate(interrupt_info["options"], 1):
|
for idx, opt in enumerate(interrupt_data["options"], 1):
|
||||||
print(f"{idx}. {opt}")
|
print(f"{idx}. {opt}")
|
||||||
choice_idx = int(input("Enter number: ")) - 1
|
choice = input("Выберите номер: ").strip()
|
||||||
chosen = interrupt_info["options"][choice_idx]
|
try:
|
||||||
# Resume the graph with the chosen value
|
selected = interrupt_data["options"][int(choice) - 1]
|
||||||
state = graph.invoke(state, {"__resume__": chosen})
|
state["human_value"] = selected
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
print("Неверный выбор. Повторите.")
|
||||||
else:
|
else:
|
||||||
# Graph finished
|
|
||||||
break
|
break
|
||||||
|
|
||||||
print("Final state:", state)
|
print("\nИтоговое состояние:")
|
||||||
|
print(state)
|
||||||
Reference in New Issue
Block a user