Spaces:
Runtime error
Runtime error
import os | |
import gradio as gr | |
import pandas as pd | |
import openai | |
from dotenv import load_dotenv | |
# Load environment variables | |
load_dotenv() | |
# Set up OpenAI API key | |
openai.api_key = os.getenv("OPENAI_API_KEY") | |
# Simple database using pandas DataFrames | |
class SimpleDatabase: | |
def __init__(self): | |
# Sample product data | |
self.products = pd.DataFrame({ | |
'product_id': [1, 2, 3, 4, 5], | |
'name': ['Laptop', 'Smartphone', 'Headphones', 'Monitor', 'Keyboard'], | |
'category': ['Electronics', 'Electronics', 'Audio', 'Electronics', 'Accessories'], | |
'price': [1200, 800, 150, 300, 80], | |
'stock': [10, 25, 50, 15, 30] | |
}) | |
# Sample transactions data | |
self.transactions = pd.DataFrame({ | |
'transaction_id': [101, 102, 103, 104, 105, 106, 107], | |
'product_id': [1, 2, 3, 1, 5, 2, 4], | |
'quantity': [1, 2, 3, 1, 2, 1, 2], | |
'date': ['2025-04-29', '2025-04-29', '2025-04-28', '2025-04-28', '2025-04-27', '2025-04-29', '2025-04-29'], | |
'revenue': [1200, 1600, 450, 1200, 160, 800, 600] | |
}) | |
def query_database(self, query_type, **kwargs): | |
"""Execute queries on the database based on query type""" | |
if query_type == "product_info": | |
if 'product_name' in kwargs: | |
return self.products[self.products['name'].str.lower() == kwargs['product_name'].lower()] | |
elif 'product_id' in kwargs: | |
return self.products[self.products['product_id'] == kwargs['product_id']] | |
else: | |
return self.products | |
elif query_type == "max_revenue_product": | |
date_filter = kwargs.get('date', '2025-04-29') # Default to today | |
# Group by product_id and calculate total revenue for the specified date | |
daily_revenue = self.transactions[self.transactions['date'] == date_filter].groupby( | |
'product_id')['revenue'].sum().reset_index() | |
if daily_revenue.empty: | |
return "No sales data found for that date." | |
# Find the product with max revenue | |
max_revenue_product_id = daily_revenue.loc[daily_revenue['revenue'].idxmax()]['product_id'] | |
max_revenue = daily_revenue.loc[daily_revenue['revenue'].idxmax()]['revenue'] | |
# Get product details | |
product_details = self.products[self.products['product_id'] == max_revenue_product_id].iloc[0] | |
return { | |
'product_name': product_details['name'], | |
'revenue': max_revenue, | |
'date': date_filter | |
} | |
elif query_type == "inventory_check": | |
product_name = kwargs.get('product_name') | |
if product_name: | |
product = self.products[self.products['name'].str.lower() == product_name.lower()] | |
if not product.empty: | |
return {'product': product_name, 'stock': product.iloc[0]['stock']} | |
return f"Product '{product_name}' not found." | |
return self.products[['name', 'stock']] | |
return "Query type not supported" | |
class QueryRouter: | |
def __init__(self): | |
"""Initialize the query router""" | |
pass | |
def _classify_query(self, query): | |
"""Classify the query to determine which agent should handle it""" | |
# Use OpenAI to classify the query | |
response = openai.chat.completions.create( | |
model="gpt-3.5-turbo", | |
messages=[ | |
{"role": "system", "content": """ | |
You are a query classifier for a shop assistant system. | |
Classify customer queries into one of these categories: | |
- max_revenue_product: Questions about which product generated the most revenue (today or on a specific date) | |
- inventory_check: Questions about product availability or stock levels | |
- product_info: Questions about product details, pricing, etc. | |
- general_knowledge: Questions that require general knowledge not related to specific shop data | |
Return ONLY the category as a single word without any explanation. | |
"""}, | |
{"role": "user", "content": query} | |
], | |
temperature=0 | |
) | |
# Extract the query type from the response | |
query_type = response.choices[0].message.content.strip().lower() | |
return query_type | |
def _extract_parameters(self, query, query_type): | |
"""Extract relevant parameters from the query based on query type""" | |
# Use OpenAI to extract parameters | |
prompt_content = f""" | |
Extract parameters from this customer query: "{query}" | |
Query type: {query_type} | |
For max_revenue_product: | |
- date (in YYYY-MM-DD format, extract "today" as today's date which is 2025-04-29) | |
For inventory_check or product_info: | |
- product_name (the name of the product being asked about) | |
Return ONLY a valid JSON object with the extracted parameters, nothing else. | |
Example: {{"product_name": "laptop"}} or {{"date": "2025-04-29"}} | |
""" | |
response = openai.chat.completions.create( | |
model="gpt-3.5-turbo", | |
messages=[ | |
{"role": "system", "content": "You extract parameters from customer queries for a shop assistant."}, | |
{"role": "user", "content": prompt_content} | |
], | |
temperature=0, | |
response_format={"type": "json_object"} | |
) | |
# Parse the JSON response | |
import json | |
try: | |
parameters = json.loads(response.choices[0].message.content) | |
return parameters | |
except json.JSONDecodeError: | |
return {} | |
def _handle_general_knowledge(self, query): | |
"""Handle general knowledge queries using OpenAI""" | |
response = openai.chat.completions.create( | |
model="gpt-3.5-turbo", | |
messages=[ | |
{"role": "system", "content": """ | |
You are a helpful assistant for a shop. Answer the customer's question | |
using your general knowledge. Keep answers brief and focused. | |
"""}, | |
{"role": "user", "content": query} | |
], | |
temperature=0.7, | |
max_tokens=150 | |
) | |
return response.choices[0].message.content | |
def _format_response(self, query_type, data): | |
"""Format the response based on query type and data""" | |
if query_type == "max_revenue_product": | |
if isinstance(data, str): | |
return data | |
return f"The product with the highest revenue on {data['date']} is {data['product_name']} with ${data['revenue']} in sales." | |
elif query_type == "inventory_check": | |
if isinstance(data, str): | |
return data | |
if isinstance(data, dict) and 'product' in data: | |
return f"We currently have {data['stock']} units of {data['product']} in stock." | |
return "Here's our current inventory: " + ", ".join([f"{row['name']}: {row['stock']} units" for _, row in data.iterrows()]) | |
elif query_type == "product_info": | |
if data.empty: | |
return "Product not found." | |
if len(data) == 1: | |
product = data.iloc[0] | |
return f"{product['name']} ({product['category']}): ${product['price']}. We have {product['stock']} units in stock." | |
return "Here are our products: " + ", ".join([f"{row['name']}: ${row['price']}" for _, row in data.iterrows()]) | |
return str(data) | |
def process(self, query, db): | |
"""Process the query and return a response""" | |
# Classify the query | |
query_type = self._classify_query(query) | |
# If it's a general knowledge query, handle it differently | |
if query_type == "general_knowledge": | |
return self._handle_general_knowledge(query) | |
# Extract parameters from the query | |
parameters = self._extract_parameters(query, query_type) | |
# Query the database | |
result = db.query_database(query_type, **parameters) | |
# Format the response | |
response = self._format_response(query_type, result) | |
return response | |
# Initialize database and router | |
db = SimpleDatabase() | |
router = QueryRouter() | |
def process_query(query): | |
"""Process the user query and return a response""" | |
if not query.strip(): | |
return "Please ask a question about our shop products or services." | |
response = router.process(query, db) | |
return response | |
# Create Gradio interface | |
demo = gr.Interface( | |
fn=process_query, | |
inputs=gr.Textbox( | |
placeholder="Ask about product pricing, inventory, sales, or any other question...", | |
label="Customer Query" | |
), | |
outputs=gr.Textbox(label="Shop Assistant Response"), | |
title="Shop Voice Box Assistant", | |
description="Ask questions about products, inventory, sales, or general questions.", | |
examples=[ | |
["What's the maximum revenue product today?"], | |
["How many laptops do we have in stock?"], | |
["Tell me about the smartphone."], | |
["What's the weather like today?"] | |
] | |
) | |
# Launch the app | |
if __name__ == "__main__": | |
demo.launch() |