voicebot / app.py
saadawaissheikh's picture
Update app.py
63a20dd verified
raw
history blame
4.57 kB
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)