File size: 4,573 Bytes
c2b6ff9
401512a
c2b6ff9
 
 
 
63a20dd
c2b6ff9
63a20dd
 
 
 
2549820
 
 
63a20dd
 
778c37c
63a20dd
 
 
778c37c
63a20dd
c2b6ff9
 
 
 
 
 
 
 
778c37c
 
 
63a20dd
c2b6ff9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63a20dd
 
c2b6ff9
a892d49
 
c2b6ff9
 
 
 
 
 
 
 
63a20dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778c37c
a892d49
63a20dd
778c37c
 
c2b6ff9
63a20dd
c2b6ff9
778c37c
c2b6ff9
778c37c
c2b6ff9
 
 
778c37c
 
63a20dd
 
 
 
 
 
 
 
 
 
 
 
778c37c
63a20dd
778c37c
63a20dd
778c37c
c2b6ff9
63a20dd
c2b6ff9
63a20dd
 
778c37c
 
c2b6ff9
63a20dd
c2b6ff9
 
778c37c
c2b6ff9
778c37c
 
c2b6ff9
63a20dd
 
c2b6ff9
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import os
import re
import gradio as gr
from gtts import gTTS
from datetime import datetime
from openpyxl import Workbook, load_workbook
import google.generativeai as genai

# LangChain memory
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage, AIMessage
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain

# ========== SETUP ==========
genai.configure(api_key="AIzaSyBJFmohAmhmqXQlM3fVxj8MLegVb26kyJk")

llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash", convert_system_message_to_human=True)
memory = ConversationBufferMemory(return_messages=True)
chain = ConversationChain(llm=llm, memory=memory, verbose=False)

# Menu & State
MENU = {
    "Cheeseburger": 5.99,
    "Fries": 2.99,
    "Coke": 1.99,
    "Pizza": 12.99,
    "Chicken Wings": 7.99,
    "Salad": 6.99
}
order = []
customer_name = ""

# Excel Setup
EXCEL_FILE = "orders.xlsx"
def setup_excel():
    if not os.path.exists(EXCEL_FILE):
        wb = Workbook()
        ws = wb.active
        ws.title = "Orders"
        ws.append(["Order ID", "Date", "Customer", "Items", "Total", "Time"])
        wb.save(EXCEL_FILE)
setup_excel()

def save_to_excel(name, items):
    wb = load_workbook(EXCEL_FILE)
    ws = wb.active
    order_id = f"ORD{ws.max_row:04d}"
    now = datetime.now()
    total = sum(qty * MENU[item] for item, qty in items)
    items_str = ", ".join(f"{qty} x {item}" for item, qty in items)
    ws.append([order_id, now.strftime("%Y-%m-%d"), name, items_str, f"${total:.2f}", now.strftime("%H:%M:%S")])
    wb.save(EXCEL_FILE)
    return order_id

# Voice

def clean_text(text):
    text = re.sub(r"\*\*(.*?)\*\*", r"\1", text)
    text = re.sub(r"Bot\s*:\s*", "", text, flags=re.IGNORECASE)
    return text.strip()

def speak(text, filename="response.mp3"):
    cleaned = clean_text(text)
    tts = gTTS(text=cleaned)
    tts.save(filename)
    return filename

# Prompt Template
system_prompt = """
You are a helpful restaurant assistant at 'Systaurant'.

Your job is to:
- Greet the user and ask their name if not known.
- Show the menu if requested.
- Extract food items and quantities from the customer's message.
- If the user says 'done', summarize the order and ask for confirmation.
- If confirmed, respond with a thank you and order ID.
- Keep the tone friendly and human. Do not prefix with "Bot:".

Menu:
{menu}
Customer name: {name}
Order so far: {summary}
"""

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("human", "{input}")
])

def generate_response(user_input):
    global customer_name, order

    # Track name
    if "my name is" in user_input.lower():
        customer_name = user_input.split("my name is")[-1].strip().split()[0].title()

    # Track items
    for item in MENU:
        if item.lower() in user_input.lower():
            qty = 1
            for word in user_input.lower().split():
                if word.isdigit():
                    qty = int(word)
                    break
            order.append((item, qty))

    # Confirmation
    if "confirm" in user_input.lower() or "yes" in user_input.lower():
        if customer_name and order:
            order_id = save_to_excel(customer_name, order)
            memory.chat_memory.add_user_message(user_input)
            memory.chat_memory.add_ai_message(f"βœ… Your order ID is {order_id}. Thank you for ordering from Saad's Restaurant!")
            return f"βœ… Your order ID is {order_id}. Thank you for ordering from Saad's Restaurant!"

    menu_text = "\n".join([f"{item}: ${price}" for item, price in MENU.items()])
    summary = ", ".join([f"{qty} x {item}" for item, qty in order]) if order else "No items yet"

    filled_prompt = prompt.invoke({
        "input": user_input,
        "menu": menu_text,
        "name": customer_name or "Not provided",
        "summary": summary
    })

    return chain.invoke(filled_prompt.to_string())

def handle_chat(user_input):
    bot_reply = generate_response(user_input)
    audio_file = speak(bot_reply)
    return bot_reply, audio_file

# Gradio Interface
gr.Interface(
    fn=handle_chat,
    inputs=gr.Textbox(label="πŸ‘€ You", placeholder="Type your order..."),
    outputs=[
        gr.Textbox(label="πŸ€– Bot Response"),
        gr.Audio(label="πŸ”Š Speaking", autoplay=True)
    ],
    title="πŸ” SysTaurant Voice Bot with Memory",
    description="Place your restaurant order through chat with memory.",
    theme="soft"
).launch(share=True)