Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,10 +6,9 @@ import google.generativeai as genai
|
|
| 6 |
from PIL import Image
|
| 7 |
import PyPDF2
|
| 8 |
import os
|
| 9 |
-
import json
|
| 10 |
from langchain.agents import initialize_agent, Tool
|
| 11 |
from langchain.agents.agent_types import AgentType
|
| 12 |
-
from
|
| 13 |
from dotenv import load_dotenv
|
| 14 |
|
| 15 |
# Load environment variables
|
|
@@ -25,22 +24,49 @@ def configure_gemini(api_key):
|
|
| 25 |
model = configure_gemini(os.environ['GOOGLE_API_KEY'])
|
| 26 |
|
| 27 |
# Initialize Gemini models
|
| 28 |
-
llm_flash_exp = ChatGoogleGenerativeAI(
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
class SmartShoppingAssistant:
|
| 31 |
def __init__(self, products_df):
|
| 32 |
self.df = products_df
|
| 33 |
self.memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
|
| 34 |
self.setup_agent()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
def setup_agent(self):
|
| 37 |
"""Set up the LangChain agent with necessary tools"""
|
| 38 |
def search_products(query):
|
| 39 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
if 'RetailPrice' in self.df.columns:
|
| 41 |
self.df['RetailPrice'] = pd.to_numeric(self.df['RetailPrice'].str.replace('$', ''), errors='coerce')
|
| 42 |
|
| 43 |
-
results = self.
|
| 44 |
return results.to_string() if not results.empty else "No products found matching your criteria."
|
| 45 |
except Exception as e:
|
| 46 |
return f"Error executing query: {str(e)}"
|
|
@@ -49,7 +75,7 @@ class SmartShoppingAssistant:
|
|
| 49 |
Tool(
|
| 50 |
name="Product Search",
|
| 51 |
func=search_products,
|
| 52 |
-
description="Search for products in the supermarket database"
|
| 53 |
)
|
| 54 |
]
|
| 55 |
|
|
@@ -58,27 +84,33 @@ class SmartShoppingAssistant:
|
|
| 58 |
memory=self.memory,
|
| 59 |
llm=llm_flash_exp,
|
| 60 |
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
|
| 61 |
-
verbose=True
|
|
|
|
| 62 |
)
|
| 63 |
|
| 64 |
def process_natural_language_query(self, query):
|
| 65 |
"""Process natural language query and return relevant products"""
|
|
|
|
|
|
|
|
|
|
| 66 |
try:
|
| 67 |
prompt = f"""
|
| 68 |
-
Convert this shopping request into a
|
| 69 |
-
|
| 70 |
|
| 71 |
Shopping request: {query}
|
| 72 |
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
Return only the
|
|
|
|
|
|
|
| 76 |
"""
|
| 77 |
|
| 78 |
response = llm_flash_exp.predict(prompt)
|
| 79 |
structured_query = response.strip()
|
| 80 |
|
| 81 |
-
result = self.agent.run(f"
|
| 82 |
return result
|
| 83 |
except Exception as e:
|
| 84 |
return f"Error processing query: {str(e)}"
|
|
@@ -103,6 +135,7 @@ class SmartShoppingAssistant:
|
|
| 103 |
except Exception as e:
|
| 104 |
return f"Error processing PDF: {str(e)}"
|
| 105 |
|
|
|
|
| 106 |
def main():
|
| 107 |
st.set_page_config(page_title="Smart Shopping Assistant", layout="wide")
|
| 108 |
st.title("🛒 Smart Shopping Assistant")
|
|
|
|
| 6 |
from PIL import Image
|
| 7 |
import PyPDF2
|
| 8 |
import os
|
|
|
|
| 9 |
from langchain.agents import initialize_agent, Tool
|
| 10 |
from langchain.agents.agent_types import AgentType
|
| 11 |
+
from difflib import get_close_matches
|
| 12 |
from dotenv import load_dotenv
|
| 13 |
|
| 14 |
# Load environment variables
|
|
|
|
| 24 |
model = configure_gemini(os.environ['GOOGLE_API_KEY'])
|
| 25 |
|
| 26 |
# Initialize Gemini models
|
| 27 |
+
llm_flash_exp = ChatGoogleGenerativeAI(
|
| 28 |
+
model="gemini-2.0-flash-exp",
|
| 29 |
+
max_retries=2 # Limit retries to 2
|
| 30 |
+
)
|
| 31 |
|
| 32 |
class SmartShoppingAssistant:
|
| 33 |
def __init__(self, products_df):
|
| 34 |
self.df = products_df
|
| 35 |
self.memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
|
| 36 |
self.setup_agent()
|
| 37 |
+
|
| 38 |
+
def find_closest_product(self, product_name, threshold=0.6):
|
| 39 |
+
"""Find the closest matching product name using fuzzy matching"""
|
| 40 |
+
matches = get_close_matches(
|
| 41 |
+
product_name.upper(),
|
| 42 |
+
self.df['ProductName'].str.upper().tolist(),
|
| 43 |
+
n=1,
|
| 44 |
+
cutoff=threshold
|
| 45 |
+
)
|
| 46 |
+
return matches[0] if matches else None
|
| 47 |
+
|
| 48 |
+
def search_products_fuzzy(self, product_names):
|
| 49 |
+
"""Search for products using fuzzy matching"""
|
| 50 |
+
results = pd.DataFrame()
|
| 51 |
+
for name in product_names:
|
| 52 |
+
closest_match = self.find_closest_product(name)
|
| 53 |
+
if closest_match:
|
| 54 |
+
matched_products = self.df[self.df['ProductName'].str.upper() == closest_match.upper()]
|
| 55 |
+
results = pd.concat([results, matched_products])
|
| 56 |
+
return results
|
| 57 |
|
| 58 |
def setup_agent(self):
|
| 59 |
"""Set up the LangChain agent with necessary tools"""
|
| 60 |
def search_products(query):
|
| 61 |
try:
|
| 62 |
+
# Extract product names from the query
|
| 63 |
+
product_names = [name.strip('"\'') for name in query.split(' or ')]
|
| 64 |
+
product_names = [name.split('==')[1].strip() if '==' in name else name for name in product_names]
|
| 65 |
+
|
| 66 |
if 'RetailPrice' in self.df.columns:
|
| 67 |
self.df['RetailPrice'] = pd.to_numeric(self.df['RetailPrice'].str.replace('$', ''), errors='coerce')
|
| 68 |
|
| 69 |
+
results = self.search_products_fuzzy(product_names)
|
| 70 |
return results.to_string() if not results.empty else "No products found matching your criteria."
|
| 71 |
except Exception as e:
|
| 72 |
return f"Error executing query: {str(e)}"
|
|
|
|
| 75 |
Tool(
|
| 76 |
name="Product Search",
|
| 77 |
func=search_products,
|
| 78 |
+
description="Search for products in the supermarket database using fuzzy matching"
|
| 79 |
)
|
| 80 |
]
|
| 81 |
|
|
|
|
| 84 |
memory=self.memory,
|
| 85 |
llm=llm_flash_exp,
|
| 86 |
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
|
| 87 |
+
verbose=True,
|
| 88 |
+
max_iterations=3 # Limit the number of iterations
|
| 89 |
)
|
| 90 |
|
| 91 |
def process_natural_language_query(self, query):
|
| 92 |
"""Process natural language query and return relevant products"""
|
| 93 |
+
|
| 94 |
+
product_list = self.df['ProductName'].tolist()
|
| 95 |
+
product_string = ", ".join(product_list)
|
| 96 |
try:
|
| 97 |
prompt = f"""
|
| 98 |
+
Convert this shopping request into a list of product names to search for. The response should be in the format:
|
| 99 |
+
ProductName == "PRODUCT1" or ProductName == "PRODUCT2" or ProductName == "PRODUCT3"
|
| 100 |
|
| 101 |
Shopping request: {query}
|
| 102 |
|
| 103 |
+
Available products will be matched approximately or use you intelligent to look at product and list and see the ones that match
|
| 104 |
+
, so focus on the main product names.
|
| 105 |
+
Return only the search string, nothing else.
|
| 106 |
+
|
| 107 |
+
This is the list of products: {product_string}
|
| 108 |
"""
|
| 109 |
|
| 110 |
response = llm_flash_exp.predict(prompt)
|
| 111 |
structured_query = response.strip()
|
| 112 |
|
| 113 |
+
result = self.agent.run(f"Search for products matching the specified names: {structured_query}")
|
| 114 |
return result
|
| 115 |
except Exception as e:
|
| 116 |
return f"Error processing query: {str(e)}"
|
|
|
|
| 135 |
except Exception as e:
|
| 136 |
return f"Error processing PDF: {str(e)}"
|
| 137 |
|
| 138 |
+
# Main function remains the same
|
| 139 |
def main():
|
| 140 |
st.set_page_config(page_title="Smart Shopping Assistant", layout="wide")
|
| 141 |
st.title("🛒 Smart Shopping Assistant")
|