Option presentation
Once options are on screen, the user can pick one, change something, or abandon. The graph has to handle every case without dropping the thread. The key insight is that stage = "proposing" changes how the router interprets the next turn.
def route_from_intent(state: BookingState) -> str:
intent = state.get("_intent")
stage = state.get("stage") or "routing"
choice = state.get("_choice_index")
# Already proposed options
if stage == "proposing":
if choice or intent == "confirm":
return "confirm_booking"
# User is updating slots (passengers, return date) → re-propose
return "propose_options"When stage is "proposing", routing narrows down: confirm if a choice or confirm intent came through, otherwise re-propose after applying whatever change the user made. No slot collection can happen from here, by design.
Proposing stage: how the turn ends
Quiz: Quiz
Loading practice…