ADK-Bot / engine /flow_router.py
Mr-Help's picture
Update engine/flow_router.py
6d35781 verified
from engine.states import (
START,
WAITING_MAIN_MENU,
WAITING_USER_TYPE,
WAITING_AUDIENCE,
WAITING_PRIOR_STUDY,
WAITING_BEGINNER_SCHEDULE_CHOICE,
WAITING_PDF_102_CONFIRMATION,
WAITING_PLACEMENT_TEST_CONFIRMATION,
WAITING_CURRENT_STUDENT_ACTION,
WAITING_SUPPORT_QUESTION,
WAITING_LEVEL_SELECTION,
WAITING_PAYMENT_METHOD,
WAITING_COMPLAINT_FORM,
HANDOFF_DONE,
)
from knowledge.replies import (
greeting_main_menu_reply,
ask_new_or_current_reply,
ask_audience_reply,
ask_prior_study_reply,
beginner_schedule_reply,
pdf_102_reply,
placement_test_reply,
current_student_menu_reply,
support_question_reply,
ask_level_selection_reply,
payment_methods_reply,
unknown_reply,
)
from knowledge.message_understanding import classify_message
from handoff.sales import create_sales_handoff_result
from handoff.support import create_support_handoff_result
from handoff.complaints import create_complaint_flow_result
def route_message(state: str, text: str, session: dict):
flow_data = session.get("flow_data", {}) or {}
parsed = classify_message(state, text, flow_data)
kind = parsed["kind"]
value = parsed["value"]
entities = parsed.get("entities", {}) or {}
print("========== MESSAGE CLASSIFICATION ==========")
print(f"state: {state}")
print(f"text: {text}")
print(f"kind: {kind}")
print(f"value: {value}")
print(f"entities: {entities}")
print(f"source: {parsed.get('source')}")
if parsed.get("raw_model_output") is not None:
print(f"raw_model_output: {parsed.get('raw_model_output')}")
print("============================================")
# =========================
# Global topic switches
# =========================
if kind == "topic_switch":
if value in ["restart", "new_topic", "courses_info"]:
return {
"next_state": WAITING_MAIN_MENU,
"flow_data": {},
"reply": "تمام، نبدأ من جديد. إنت طالب جديد ولا طالب حالي؟"
}
if value == "complaint":
return create_complaint_flow_result(flow_data)
if value == "direct_support":
return create_support_handoff_result(
flow_data=flow_data,
summary=f"طلب تواصل مباشر أثناء المحادثة: {text}"
)
if value == "children_courses":
new_flow = dict(flow_data)
new_flow["customer_type"] = "new"
new_flow["audience"] = "children"
return ask_prior_study_reply(new_flow)
if value == "adults_courses":
new_flow = dict(flow_data)
new_flow["customer_type"] = "new"
new_flow["audience"] = "adults"
return ask_prior_study_reply(new_flow)
if value == "new_student":
new_flow = dict(flow_data)
new_flow["customer_type"] = "new"
return ask_audience_reply(new_flow)
if value == "current_student":
new_flow = dict(flow_data)
new_flow["customer_type"] = "current"
return current_student_menu_reply(new_flow)
# =========================
# START
# =========================
if state == START:
return greeting_main_menu_reply(flow_data)
# =========================
# WAITING_MAIN_MENU
# =========================
if state == WAITING_MAIN_MENU:
return ask_new_or_current_reply(flow_data)
# =========================
# WAITING_USER_TYPE
# =========================
if state == WAITING_USER_TYPE:
if kind == "direct_answer" and value == "new_student":
flow_data.update(entities)
return ask_audience_reply(flow_data)
if kind == "direct_answer" and value == "current_student":
flow_data.update(entities)
return current_student_menu_reply(flow_data)
return {
"next_state": WAITING_USER_TYPE,
"flow_data": flow_data,
"reply": "تمام، محتاج أعرف الأول: إنت طالب جديد ولا طالب حالي؟"
}
# =========================
# WAITING_AUDIENCE
# =========================
if state == WAITING_AUDIENCE:
if kind == "direct_answer" and value == "adults":
flow_data.update(entities)
return ask_prior_study_reply(flow_data)
if kind == "direct_answer" and value == "children":
flow_data.update(entities)
return ask_prior_study_reply(flow_data)
return {
"next_state": WAITING_AUDIENCE,
"flow_data": flow_data,
"reply": "تمام، الكورس للكبار ولا للأطفال؟"
}
# =========================
# WAITING_PRIOR_STUDY
# =========================
if state == WAITING_PRIOR_STUDY:
if kind == "direct_answer" and value == "prior_study_no":
flow_data.update(entities)
return beginner_schedule_reply(flow_data)
if kind == "direct_answer" and value == "prior_study_yes":
flow_data.update(entities)
return placement_test_reply(flow_data)
return {
"next_state": WAITING_PRIOR_STUDY,
"flow_data": flow_data,
"reply": "هل درست اللغة الألمانية قبل كده؟ رد بنعم أو لا."
}
# =========================
# WAITING_BEGINNER_SCHEDULE_CHOICE
# =========================
if state == WAITING_BEGINNER_SCHEDULE_CHOICE:
if kind == "state_switch" and value == "switch_to_prior_study_true":
new_flow = dict(flow_data)
new_flow.update(entities)
return placement_test_reply(new_flow)
if kind == "state_switch" and value == "switch_to_prior_study_false":
new_flow = dict(flow_data)
new_flow.update(entities)
return beginner_schedule_reply(new_flow)
if kind == "state_switch" and value == "support_needed":
return create_support_handoff_result(
flow_data=flow_data,
summary="استفسار عن مواعيد كورسات المبتدئين"
)
if kind == "direct_answer" and value in ["confirm_schedule_reviewed", "proceed_booking"]:
return pdf_102_reply(flow_data)
if kind == "unclear":
return {
"next_state": WAITING_BEGINNER_SCHEDULE_CHOICE,
"flow_data": flow_data,
"reply": "تقصد تكمل الحجز، ولا بتسأل عن حالة لو كنت درست ألماني قبل كده؟"
}
# =========================
# WAITING_PDF_102_CONFIRMATION
# =========================
if state == WAITING_PDF_102_CONFIRMATION:
if kind == "state_switch" and value == "switch_to_prior_study_true":
new_flow = dict(flow_data)
new_flow.update(entities)
return placement_test_reply(new_flow)
if kind == "state_switch" and value == "switch_to_prior_study_false":
new_flow = dict(flow_data)
new_flow.update(entities)
return beginner_schedule_reply(new_flow)
if kind == "state_switch" and value == "support_needed":
return create_support_handoff_result(
flow_data=flow_data,
summary="استفسار بعد إرسال ملف 102"
)
if kind == "direct_answer" and value == "confirm_pdf_reviewed":
return payment_methods_reply(flow_data)
return {
"next_state": WAITING_PDF_102_CONFIRMATION,
"flow_data": flow_data,
"reply": "بعد ما تطلع على الملف، ابعتلي تم عشان أكمل معاك إجراءات الدفع والحجز."
}
# =========================
# WAITING_PLACEMENT_TEST_CONFIRMATION
# =========================
if state == WAITING_PLACEMENT_TEST_CONFIRMATION:
if kind == "state_switch" and value == "switch_to_prior_study_false":
new_flow = dict(flow_data)
new_flow.update(entities)
return beginner_schedule_reply(new_flow)
if kind == "state_switch" and value == "switch_to_prior_study_true":
new_flow = dict(flow_data)
new_flow.update(entities)
return placement_test_reply(new_flow)
if kind == "state_switch" and value == "support_needed":
return create_support_handoff_result(
flow_data=flow_data,
summary="استفسار عن اختبار تحديد المستوى"
)
if kind == "direct_answer" and value == "confirm_placement_test_reviewed":
return create_sales_handoff_result(
flow_data=flow_data,
summary="عميل اختار أو مهتم باختبار تحديد مستوى"
)
return {
"next_state": WAITING_PLACEMENT_TEST_CONFIRMATION,
"flow_data": flow_data,
"reply": "بعد ما تراجع مواعيد اختبار تحديد المستوى، ابعتلي تم أو قولّي لو محتاج مساعدة."
}
# =========================
# WAITING_CURRENT_STUDENT_ACTION
# =========================
if state == WAITING_CURRENT_STUDENT_ACTION:
if kind == "direct_answer" and value == "current_student_support":
return support_question_reply(flow_data)
if kind == "direct_answer" and value == "current_student_next_level":
return ask_level_selection_reply(flow_data)
return {
"next_state": WAITING_CURRENT_STUDENT_ACTION,
"flow_data": flow_data,
"reply": "تحب استفسار بخصوص الكورس ولا حجز المستوى التالي؟"
}
# =========================
# WAITING_SUPPORT_QUESTION
# =========================
if state == WAITING_SUPPORT_QUESTION:
if kind == "direct_answer" and value == "support_question_text":
flow_data.update(entities)
return create_support_handoff_result(
flow_data=flow_data,
summary=f"استفسار طالب حالي: {text}"
)
return {
"next_state": WAITING_SUPPORT_QUESTION,
"flow_data": flow_data,
"reply": "اكتبلي استفسارك بالتفصيل، وأنا هرفعه لفريق خدمة العملاء."
}
# =========================
# WAITING_LEVEL_SELECTION
# =========================
if state == WAITING_LEVEL_SELECTION:
if kind == "direct_answer" and value == "level_selected":
flow_data.update(entities)
return payment_methods_reply(flow_data)
if kind == "state_switch" and value == "support_needed":
return create_support_handoff_result(
flow_data=flow_data,
summary="طالب حالي محتاج مساعدة في اختيار المستوى التالي"
)
return {
"next_state": WAITING_LEVEL_SELECTION,
"flow_data": flow_data,
"reply": "قولّي المستوى اللي تحب تحجزه: 1A أو 2A أو 1B أو 1C2/B."
}
# =========================
# WAITING_PAYMENT_METHOD
# =========================
if state == WAITING_PAYMENT_METHOD:
if kind == "direct_answer" and value == "payment_method_selected":
flow_data.update(entities)
payment_method = flow_data.get("payment_method")
payment_summaries = {
"branch_or_cash": "عميل جاهز للحجز واختار الدفع كاش أو في الفرع",
"bank_transfer": "عميل جاهز للحجز واختار تحويل بنكي",
"vodafone_cash": "عميل جاهز للحجز واختار Vodafone Cash",
"card": "عميل جاهز للحجز واختار الدفع بالبطاقة",
"installments": "عميل مهتم بالتقسيط",
}
return create_sales_handoff_result(
flow_data=flow_data,
summary=payment_summaries[payment_method]
)
if kind == "state_switch" and value == "support_needed":
return create_support_handoff_result(
flow_data=flow_data,
summary="استفسار عن طرق الدفع أو إتمام الحجز"
)
return {
"next_state": WAITING_PAYMENT_METHOD,
"flow_data": flow_data,
"reply": "اختار طريقة الدفع المناسبة: الفرع / تحويل بنكي / Vodafone Cash / Visa / تقسيط Value."
}
# =========================
# WAITING_COMPLAINT_FORM
# =========================
if state == WAITING_COMPLAINT_FORM:
if kind == "direct_answer" and value == "complaint_form_submitted":
return {
"next_state": WAITING_COMPLAINT_FORM,
"flow_data": flow_data,
"reply": "تمام، بعد مراجعة الشكوى هيتم التواصل معاك. ولو حابب تكتب أي تفاصيل إضافية ابعتها هنا."
}
return {
"next_state": WAITING_COMPLAINT_FORM,
"flow_data": flow_data,
"reply": "سجّل الشكوى من الفورم أولًا، ولو احتجت مساعدة ابعتلي."
}
# =========================
# HANDOFF_DONE
# =========================
if state == HANDOFF_DONE:
if kind == "direct_answer" and value == "thanks":
return {
"next_state": HANDOFF_DONE,
"flow_data": flow_data,
"reply": "العفو، تحت أمرك في أي وقت."
}
if kind == "topic_switch":
if value in ["restart", "new_topic", "courses_info"]:
return {
"next_state": WAITING_MAIN_MENU,
"flow_data": {},
"reply": "تمام، نبدأ من جديد. إنت طالب جديد ولا طالب حالي؟"
}
if value == "children_courses":
new_flow = {}
new_flow["customer_type"] = "new"
new_flow["audience"] = "children"
return ask_prior_study_reply(new_flow)
if value == "adults_courses":
new_flow = {}
new_flow["customer_type"] = "new"
new_flow["audience"] = "adults"
return ask_prior_study_reply(new_flow)
if value == "new_student":
new_flow = {}
new_flow["customer_type"] = "new"
return ask_audience_reply(new_flow)
if value == "current_student":
new_flow = {}
new_flow["customer_type"] = "current"
return current_student_menu_reply(new_flow)
if value == "direct_support":
return create_support_handoff_result(
flow_data=flow_data,
summary=f"استفسار إضافي بعد handoff: {text}"
)
if value == "complaint":
return create_complaint_flow_result(flow_data)
return {
"next_state": HANDOFF_DONE,
"flow_data": flow_data,
"reply": (
"تم تسجيل طلبك بالفعل، وفريقنا هيتواصل معاك قريب.\n"
"ولو تحب تبدأ استفسار جديد، اكتب: ابدأ من جديد."
)
}
return unknown_reply(flow_data)