Write the record
The user comes back with "2" or "the morning one" or "let's do Tuesday at 9". The confirm node needs to map all of those to a specific slot option and write the record. An LLM call handles the natural language interpretation. A strict JSON contract keeps the output parseable.
async def confirm_booking(state: BookingState) -> BookingState:
options = state.get("slot_options") or []
if not options:
state["assistant_reply"] = "Let's pick a doctor first. What symptom are you experiencing?"
state["status"] = "gathering"
return state
system = (
"You interpret which slot a patient chose from a numbered list. "
"Return JSON: {\"choice_index\": 1-based int or null, \"declined\": bool}."
)
prompt = (
"Slots:\n"
+ "\n".join(f"{i+1}. {s}" for i, s in enumerate(options))
+ f"\nPatient reply: {state.get('user_message', '')}"
)
data = await _llm_json(prompt, system)
if data.get("declined"):
state["assistant_reply"] = "No problem. Tell me when you'd like to try again."
state["status"] = "ended"
return state
idx = data.get("choice_index")
if not isinstance(idx, int) or idx < 1 or idx > len(options):
state["assistant_reply"] = "Which slot works for you? Reply with 1, 2, or 3."
state["status"] = "ready_to_confirm"
return stateDefensive first. If slot_options is empty, the node reroutes the user to describe a symptom. If the LLM says they declined, end the turn gracefully. If the choice index is bogus, ask again without losing the context.
chosen = options[idx - 1]
doctor = state.get("doctor") or {}
patient_id = state.get("patient_id") or state.get("thread_id") or "anonymous"
appt = create_appointment(
patient_id=patient_id,
doctor_id=doctor.get("id", 0),
doctor_name=doctor.get("name", "Unknown"),
specialty=doctor.get("specialty", "general_medicine"),
slot=chosen,
)
state["slot"] = chosen
state["status"] = "confirmed"
state["assistant_reply"] = (
f"Booked! Appointment #{appt['id']} with {appt['doctor_name']} on {chosen}. "
"You'll get a reminder by email."
)
_record_event(state, "confirm_booking", {"appointment_id": appt["id"]})
return stateOnce validated, write the record. create_appointment is a db_utils helper that returns the persisted row. The node writes the slot into state, sets status = confirmed, and produces the confirmation reply.
def create_appointment(
patient_id: str,
doctor_id: int,
doctor_name: str,
specialty: str,
slot: str,
) -> Dict[str, Any]:
init_db()
conn = _connect()
try:
now = datetime.utcnow().isoformat()
cur = conn.execute(
"""
INSERT INTO appointments
(patient_id, doctor_id, doctor_name, specialty, slot, status, created_at)
VALUES (?, ?, ?, ?, ?, 'confirmed', ?)
""",
(patient_id, doctor_id, doctor_name, specialty, slot, now),
)
conn.commit()
appt_id = cur.lastrowid
return {
"id": appt_id,
"patient_id": patient_id,
"doctor_id": doctor_id,
"doctor_name": doctor_name,
"specialty": specialty,
"slot": slot,
"status": "confirmed",
"created_at": now,
}
finally:
conn.close()A parameterized INSERT returns the persisted row with its auto-generated id. The connection is closed in a finally block so a mid-write exception does not leak handles.
Quiz: Quiz
Loading practiceโฆ