├── READ.me
├── .gitignore
├── Frontend
├── src
│ ├── SCSS
│ │ ├── Components
│ │ │ ├── _bootstrap.scss
│ │ │ ├── ReponseLoader.scss
│ │ │ └── _ScreenLoader.scss
│ │ └── Frontend
│ │ │ └── _botPage.scss
│ ├── Assets
│ │ ├── bot.png
│ │ ├── user.png
│ │ ├── laptop1.png
│ │ ├── laptop2.png
│ │ └── laptop3.png
│ ├── setupTests.js
│ ├── App.test.js
│ ├── Pages
│ │ ├── Routes.js
│ │ └── Frontend
│ │ │ ├── index.js
│ │ │ └── BotPage.js
│ ├── reportWebVitals.js
│ ├── App.js
│ ├── Components
│ │ ├── Screen Loader
│ │ │ ├── ResponseLoader.js
│ │ │ └── ScreenLoader.js
│ │ └── Footer
│ │ │ └── Footer.js
│ ├── App.scss
│ ├── index.js
│ └── Context
│ │ └── AuthContext.js
├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── index.html
├── jsconfig.json
├── .gitignore
├── package.json
└── README.md
├── requirements.txt
├── ai
├── need_analysis_task.py
├── main.py
├── recommendation_task.py
├── product_search_tool.py
├── recommendation_agent.py
├── need_analysis_agent.py
├── app.py
└── app_new.py
├── verify_amazon_data.py
├── query.py
├── upload_amazon_data.py
└── README.md
/READ.me:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .venv
2 | venv
3 | __pycache__
4 | .mypy_cache
5 | agent
6 | .env
--------------------------------------------------------------------------------
/Frontend/src/SCSS/Components/_bootstrap.scss:
--------------------------------------------------------------------------------
1 | @import "~bootstrap/scss/bootstrap.scss"
--------------------------------------------------------------------------------
/Frontend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/Frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/public/favicon.ico
--------------------------------------------------------------------------------
/Frontend/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/public/logo192.png
--------------------------------------------------------------------------------
/Frontend/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/public/logo512.png
--------------------------------------------------------------------------------
/Frontend/src/Assets/bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/src/Assets/bot.png
--------------------------------------------------------------------------------
/Frontend/src/Assets/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/src/Assets/user.png
--------------------------------------------------------------------------------
/Frontend/src/Assets/laptop1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/src/Assets/laptop1.png
--------------------------------------------------------------------------------
/Frontend/src/Assets/laptop2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/src/Assets/laptop2.png
--------------------------------------------------------------------------------
/Frontend/src/Assets/laptop3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ashishpatel26/AI-Agents-hackathon/main/Frontend/src/Assets/laptop3.png
--------------------------------------------------------------------------------
/Frontend/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "src"
4 | },
5 | "include": ["src"]
6 | }
7 |
8 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | mysql-connector-python==9.0.0
2 | pandas==2.2.2
3 | crewai==0.28.8
4 | crewai-tools==0.1.6
5 | langchain==0.1.20
6 | langchain-community==0.0.38
7 | pydantic==2.9.1
8 | pydantic_core==2.23.3
--------------------------------------------------------------------------------
/Frontend/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/Frontend/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/Frontend/src/Pages/Routes.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Route, Routes } from 'react-router-dom'
3 |
4 | import Frontend from './Frontend'
5 |
6 |
7 | export default function Index() {
8 | return (
9 | <>
10 |
11 | }/>
12 |
13 | >
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/Frontend/src/Pages/Frontend/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Route, Routes } from 'react-router-dom'
3 | import BotPage from './BotPage'
4 | import Footer from 'Components/Footer/Footer'
5 |
6 | export default function Frontend() {
7 | return (
8 | <>
9 |
10 | } />
11 |
12 |
13 | >
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/Frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/Frontend/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/Frontend/src/App.js:
--------------------------------------------------------------------------------
1 | import Index from 'Pages/Routes';
2 | import "../node_modules/bootstrap/dist/js/bootstrap.bundle"
3 | import './App.scss';
4 | import ScreenLoader from 'Components/Screen Loader/ScreenLoader';
5 | import { useAuthContext } from 'Context/AuthContext';
6 |
7 | function App() {
8 | const { isApploading } = useAuthContext()
9 |
10 |
11 |
12 | if (isApploading) return
13 | else return
14 | return (
15 | <>
16 |
17 |
18 | >
19 | );
20 | }
21 |
22 | export default App;
23 |
--------------------------------------------------------------------------------
/Frontend/src/Components/Screen Loader/ResponseLoader.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default function ResponseLoader() {
4 | return (
5 | <>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | >
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/Frontend/src/Components/Footer/Footer.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default function Footer() {
4 |
5 | const year = new Date().getFullYear()
6 | return (
7 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/Frontend/src/App.scss:
--------------------------------------------------------------------------------
1 | // -------------- Components --------------
2 | @import './SCSS/Components/bootstrap';
3 | @import './SCSS/Components/ScreenLoader';
4 | @import "./SCSS/Components/ReponseLoader.scss";
5 | @import "./SCSS/Frontend/botPage";
6 |
7 | #root{
8 | display: flex;
9 | flex-direction: column;
10 | min-height: 100vh;
11 | }
12 |
13 | main{
14 | flex : 1 0 auto;
15 | }
16 |
17 |
18 | ::-webkit-scrollbar{
19 | display : none;
20 | }
21 |
22 | footer {
23 | background-color: transparent;
24 | position: fixed;
25 | width: 100%;
26 | bottom: 0;
27 | }
--------------------------------------------------------------------------------
/Frontend/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/Frontend/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import App from './App';
4 | import reportWebVitals from './reportWebVitals';
5 | import { BrowserRouter } from 'react-router-dom';
6 | import { AuthContext, AuthContextProvider } from 'Context/AuthContext';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 | root.render(
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 |
19 | // If you want to start measuring performance in your app, pass a function
20 | // to log results (for example: reportWebVitals(console.log))
21 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
22 | reportWebVitals();
23 |
--------------------------------------------------------------------------------
/ai/need_analysis_task.py:
--------------------------------------------------------------------------------
1 | from crewai import Task
2 | from textwrap import dedent
3 | from need_analysis_agent import need_analysis_agent
4 |
5 | need_analysis_task = Task(
6 | description=dedent("""
7 | Engage with the customer to understand their product requirements.
8 | Ask one question at a time, wait for the customer's response, and proceed accordingly.
9 | Your goal is to gather all necessary information to recommend the best products.
10 | Ensure all interactions are appropriate and comply with OpenAI's usage policies.
11 | """),
12 | expected_output=dedent("""
13 | A detailed summary of the customer's needs and preferences in JSON format.
14 | Include keys like 'category', 'brand', 'price_range', 'features'.
15 | """),
16 | tools=[],
17 | agent=need_analysis_agent,
18 | human_input=True
19 | )
20 |
--------------------------------------------------------------------------------
/ai/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | from dotenv import load_dotenv
3 | from crewai import Crew
4 | from need_analysis_agent import need_analysis_agent
5 | from recommendation_agent import recommendation_agent
6 | from need_analysis_task import need_analysis_task
7 | from recommendation_task import recommendation_task
8 |
9 | def main():
10 | # Load environment variables
11 | load_dotenv()
12 |
13 | # Initialize the Crew
14 | crew = Crew(
15 | agents=[need_analysis_agent, recommendation_agent],
16 | tasks=[need_analysis_task, recommendation_task],
17 | verbose=2,
18 | memory=False # Disable memory to prevent potential issues
19 | )
20 |
21 | # Run the Crew
22 | inputs = {}
23 | result = crew.kickoff(inputs=inputs)
24 |
25 | # Display the final recommendations
26 | print("\nFinal Recommendations:")
27 | print(result) # Remove ['response'] since result is a string
28 |
29 | if __name__ == "__main__":
30 | main()
31 |
--------------------------------------------------------------------------------
/verify_amazon_data.py:
--------------------------------------------------------------------------------
1 | import mysql.connector
2 |
3 | # Database connection details
4 | config = {
5 | 'user': 'Users',
6 | 'password': 'AIagents2024Green',
7 | 'host': '34.89.125.152',
8 | 'port': '3306',
9 | 'database': 'product-table',
10 | }
11 |
12 | conn = None
13 | cursor = None
14 |
15 | try:
16 | print("Connecting to the database...")
17 | conn = mysql.connector.connect(**config)
18 | cursor = conn.cursor()
19 |
20 | # Query to select some rows from the table
21 | query = "SELECT * FROM amazon_products LIMIT 10"
22 | cursor.execute(query)
23 |
24 | # Fetch and print results
25 | results = cursor.fetchall()
26 | for row in results:
27 | print(row)
28 |
29 | except mysql.connector.Error as err:
30 | print(f"Error: {err}")
31 | except Exception as ex:
32 | print(f"Exception: {ex}")
33 |
34 | finally:
35 | if cursor:
36 | cursor.close()
37 | if conn:
38 | conn.close()
39 | print("Database connection closed.")
40 |
--------------------------------------------------------------------------------
/query.py:
--------------------------------------------------------------------------------
1 | import mysql.connector
2 |
3 | # Database connection details
4 | config = {
5 | 'user': '', # Replace with your SQL username
6 | 'password': '', # Replace with your SQL password
7 | 'host': '34.89.125.152',
8 | 'port': '3306',# Replace with your SQL instance's public IP
9 | 'database': 'product-table', # Replace with your database name
10 | }
11 | conn = None
12 | cursor=None
13 | # Establish connection
14 | try:
15 | conn = mysql.connector.connect(**config)
16 | cursor = conn.cursor()
17 |
18 | # Example query: Select all rows from the 'product_table'
19 | query = "SELECT Product_Name FROM product_table"
20 | cursor.execute(query)
21 |
22 | # Fetch and display results
23 | results = cursor.fetchall()
24 | for row in results:
25 | print(row)
26 |
27 | except mysql.connector.Error as err:
28 | print(f"Error: {err}")
29 |
30 | finally:
31 | # Close the cursor and connection
32 | if cursor:
33 | cursor.close()
34 | if conn:
35 | conn.close()
36 |
--------------------------------------------------------------------------------
/Frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "product-recommender",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@google/generative-ai": "^0.16.0",
7 | "@testing-library/jest-dom": "^5.17.0",
8 | "@testing-library/react": "^13.4.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "antd": "^5.19.1",
11 | "bootstrap": "^5.3.2",
12 | "cors": "^2.8.5",
13 | "firebase": "^10.8.0",
14 | "groq-sdk": "^0.6.1",
15 | "react": "^18.2.0",
16 | "react-dom": "^18.2.0",
17 | "react-markdown": "^9.0.1",
18 | "react-router-dom": "^6.22.0",
19 | "react-scripts": "5.0.1",
20 | "sass": "^1.70.0",
21 | "web-vitals": "^2.1.4"
22 | },
23 | "scripts": {
24 | "start": "react-scripts start",
25 | "build": "react-scripts build",
26 | "test": "react-scripts test",
27 | "eject": "react-scripts eject"
28 | },
29 | "eslintConfig": {
30 | "extends": [
31 | "react-app",
32 | "react-app/jest"
33 | ]
34 | },
35 | "browserslist": {
36 | "production": [
37 | ">0.2%",
38 | "not dead",
39 | "not op_mini all"
40 | ],
41 | "development": [
42 | "last 1 chrome version",
43 | "last 1 firefox version",
44 | "last 1 safari version"
45 | ]
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Frontend/src/Context/AuthContext.js:
--------------------------------------------------------------------------------
1 | import React, { useState, createContext, useReducer, useContext, useEffect } from 'react'
2 |
3 |
4 | export const AuthContext = createContext()
5 |
6 |
7 | // export const initalState = { isAuth: false, user: {} }
8 |
9 | // const reducer = (state, action) => {
10 | // switch (action.type) {
11 | // case "Set_Logged_In":
12 | // return { isAuth: true, user: action.payload.user }
13 | // case "Set_Logged_Out":
14 | // return initalState
15 | // default:
16 | // return state
17 | // }
18 | // }
19 |
20 |
21 | const AuthContextProvider = ({ children }) => {
22 |
23 | // const [state, dispatch] = useReducer(reducer, initalState)
24 | const [isApploading, setIsApploading] = useState(true)
25 |
26 |
27 | useEffect(() => {
28 | // const token = localStorage.getItem("Token")
29 | // if (token === "true") {
30 | // const user = JSON.parse(localStorage.getItem("User"))
31 | // dispatch({ type: "Set_Logged_In", payload: { user } })
32 | // }
33 | setTimeout(() => {
34 | setIsApploading(false)
35 | }, 400)
36 | }, [])
37 |
38 | return (
39 | <>
40 |
41 | {children}
42 |
43 | >
44 | )
45 | }
46 |
47 | export const useAuthContext = () => useContext(AuthContext)
48 |
49 | export { AuthContextProvider }
--------------------------------------------------------------------------------
/ai/recommendation_task.py:
--------------------------------------------------------------------------------
1 | # recommendation_task.py
2 |
3 | from crewai import Task
4 | from textwrap import dedent
5 | from recommendation_agent import recommendation_agent
6 | from product_search_tool import ProductSearchTool
7 | import pandas as pd
8 |
9 | # Load product data
10 | product_data = pd.read_csv('ai/products.csv')
11 |
12 | # Preprocess the data to match expected column names
13 | product_data.rename(columns={
14 | 'Product Name': 'product_name',
15 | 'Product Category': 'category',
16 | 'Brand': 'brand',
17 | 'Price': 'price',
18 | 'Specifications': 'features'
19 | }, inplace=True)
20 |
21 | # Ensure price is numeric
22 | product_data['price'] = pd.to_numeric(product_data['price'], errors='coerce')
23 |
24 | # Handle missing values
25 | product_data['features'] = product_data['features'].fillna('')
26 | product_data['brand'] = product_data['brand'].fillna('')
27 | product_data['category'] = product_data['category'].fillna('')
28 |
29 | # Initialize the tool
30 | product_search_tool = ProductSearchTool(product_data=product_data)
31 |
32 | recommendation_task = Task(
33 | description=dedent("""
34 | Based on the customer's needs collected, recommend the top 2-3 products.
35 | Provide a brief description of each product and explain why it matches the customer's needs.
36 | Use the Product Search Tool to find suitable products.
37 | """),
38 | expected_output=dedent("""
39 | A list of 2-3 recommended products with descriptions and reasons for recommendation.
40 | """),
41 | tools=[product_search_tool],
42 | agent=recommendation_agent
43 | )
44 |
--------------------------------------------------------------------------------
/Frontend/src/SCSS/Components/ReponseLoader.scss:
--------------------------------------------------------------------------------
1 | /* From Uiverse.io by mobinkakei */
2 | .wrapper {
3 | width: 67px;
4 | height: 60px;
5 | position: relative;
6 | z-index: 1;
7 | margin-bottom: 30px;
8 | margin-right:20px
9 | }
10 |
11 | .circle {
12 | width: 10px;
13 | height: 10px;
14 | position: absolute;
15 | border-radius: 50%;
16 | background-color: #fff;
17 | left: 15%;
18 | transform-origin: 50%;
19 | animation: circle7124 .5s alternate infinite ease;
20 | }
21 |
22 | @keyframes circle7124 {
23 | 0% {
24 | top: 60px;
25 | height: 5px;
26 | border-radius: 50px 50px 25px 25px;
27 | transform: scaleX(1.7);
28 | }
29 |
30 | 40% {
31 | height: 20px;
32 | border-radius: 50%;
33 | transform: scaleX(1);
34 | }
35 |
36 | 100% {
37 | top: 0%;
38 | }
39 | }
40 |
41 | .circle:nth-child(2) {
42 | left: 45%;
43 | animation-delay: .2s;
44 | }
45 |
46 | .circle:nth-child(3) {
47 | left: auto;
48 | right: 15%;
49 | animation-delay: .3s;
50 | }
51 |
52 | .shadow {
53 | width: 20px;
54 | height: 4px;
55 | border-radius: 50%;
56 | background-color: rgba(0,0,0,0.9);
57 | position: absolute;
58 | top: 62px;
59 | transform-origin: 50%;
60 | z-index: -1;
61 | left: 15%;
62 | filter: blur(1px);
63 | animation: shadow046 .5s alternate infinite ease;
64 | }
65 |
66 | @keyframes shadow046 {
67 | 0% {
68 | transform: scaleX(1.5);
69 | }
70 |
71 | 40% {
72 | transform: scaleX(1);
73 | opacity: .7;
74 | }
75 |
76 | 100% {
77 | transform: scaleX(.2);
78 | opacity: .4;
79 | }
80 | }
81 |
82 | .shadow:nth-child(4) {
83 | left: 45%;
84 | animation-delay: .2s
85 | }
86 |
87 | .shadow:nth-child(5) {
88 | left: auto;
89 | right: 15%;
90 | animation-delay: .3s;
91 | }
92 |
--------------------------------------------------------------------------------
/Frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Product Recommender
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/ai/product_search_tool.py:
--------------------------------------------------------------------------------
1 | from crewai_tools import BaseTool
2 | import pandas as pd
3 | import json
4 | from typing import Any
5 | from pydantic import ConfigDict
6 |
7 | class ProductSearchTool(BaseTool):
8 | name: str = "Product Search Tool"
9 | description: str = "Searches for products based on customer preferences."
10 | product_data: pd.DataFrame
11 |
12 | model_config = ConfigDict(arbitrary_types_allowed=True)
13 |
14 | def _run(self, text: str) -> str:
15 | customer_needs = json.loads(text)
16 | filtered_products = self.product_data.copy()
17 |
18 | # Apply filters based on customer needs
19 | if 'category' in customer_needs:
20 | filtered_products = filtered_products[
21 | filtered_products['category'].str.contains(customer_needs['category'], case=False, na=False)
22 | ]
23 | if 'brand' in customer_needs:
24 | filtered_products = filtered_products[
25 | filtered_products['brand'].str.contains(customer_needs['brand'], case=False, na=False)
26 | ]
27 | if 'price_range' in customer_needs:
28 | min_price, max_price = customer_needs['price_range']
29 | filtered_products = filtered_products[
30 | (filtered_products['price'] >= min_price) & (filtered_products['price'] <= max_price)
31 | ]
32 | if 'features' in customer_needs:
33 | features = customer_needs['features'].split(',')
34 | for feature in features:
35 | feature = feature.strip()
36 | filtered_products = filtered_products[
37 | filtered_products['features'].str.contains(feature, case=False, na=False)
38 | | filtered_products['Product Description'].str.contains(feature, case=False, na=False)
39 | | filtered_products['Product Tags'].str.contains(feature, case=False, na=False)
40 | ]
41 |
42 | # Select top 2-3 products
43 | recommended_products = filtered_products.head(3)
44 | products_list = recommended_products.to_dict('records')
45 | return json.dumps(products_list)
46 |
--------------------------------------------------------------------------------
/ai/recommendation_agent.py:
--------------------------------------------------------------------------------
1 | from crewai import Agent
2 | from textwrap import dedent
3 | import json
4 |
5 | class RecommendationAgent(Agent):
6 | def __init__(self):
7 | super().__init__(
8 | role='Product Recommendation Specialist',
9 | goal='Recommend the top 2-3 products based on the customer’s needs.',
10 | backstory=dedent("""
11 | You are an expert in the store's product catalog.
12 | Use the customer's preferences to recommend the best matching products.
13 | Provide clear and helpful explanations for your recommendations.
14 | """),
15 | allow_delegation=False,
16 | verbose=True
17 | )
18 |
19 | def execute_task(self, task, context=None, tools=None, **kwargs):
20 | # Check if context is a string
21 | if isinstance(context, str):
22 | # context is the JSON string of customer needs
23 | customer_needs = json.loads(context)
24 | elif isinstance(context, dict) and 'previous_task_output' in context:
25 | # context is a dictionary with previous_task_output
26 | customer_needs = json.loads(context['previous_task_output'])
27 | else:
28 | raise ValueError("Invalid context format received by RecommendationAgent.")
29 |
30 | # Use the product search tool to find products
31 | product_search_tool = tools[0] # Assuming only one tool is passed
32 | recommended_products_json = product_search_tool._run(json.dumps(customer_needs))
33 | recommended_products = json.loads(recommended_products_json)
34 |
35 | # Generate recommendations
36 | recommendations = []
37 | for product in recommended_products:
38 | recommendation = f"Product Name: {product.get('product_name', 'N/A')}\n"
39 | recommendation += f"Description: {product.get('Product Description', 'N/A')}\n"
40 | recommendation += f"Price: ${product.get('price', 'N/A')}\n"
41 | recommendation += f"Reason: Matches your preferences.\n"
42 | recommendations.append(recommendation)
43 |
44 | # Return the recommendations as a single string
45 | return '\n\n'.join(recommendations)
46 |
47 | recommendation_agent = RecommendationAgent()
48 |
--------------------------------------------------------------------------------
/Frontend/src/SCSS/Frontend/_botPage.scss:
--------------------------------------------------------------------------------
1 | .bot-page {
2 | background-color: #333333;
3 | }
4 |
5 | .userMessage {
6 | display: flex;
7 | flex-direction: row-reverse;
8 | align-items: baseline;
9 | width: fit-content;
10 | color: white;
11 | background: #2f2f2f;
12 | padding: 12px 1px 12px 30px;
13 | }
14 |
15 | .output {
16 | display: flex;
17 | flex-direction: row-reverse;
18 | align-items: center;
19 | width: fit-content;
20 | color: white;
21 | background: #2f2f2f;
22 | padding: 12px 1px 12px 30px;
23 | }
24 |
25 |
26 | p#userInput ,p.output {
27 | color: white;
28 | display: block;
29 | width: 90%;
30 | font-size: 20px;
31 | }
32 |
33 |
34 | // uiverse input area
35 |
36 | .container-fluid.chatContaienr {
37 | height: 400px;
38 | overflow: scroll;
39 | }
40 |
41 | .send-img {
42 | width: 30px;
43 | }
44 |
45 | .send-input {
46 | display: flex;
47 | align-items: center;
48 | justify-content: space-between;
49 | background-color: #40414F;
50 | border: 1px solid #2E2F3A;
51 | border-radius: 7px;
52 | height: 66px;
53 | width: 80%;
54 | margin: 0 auto;
55 | position: absolute;
56 | bottom: 36px;
57 | left: 10%;
58 | padding: 0px 13px;
59 | color: white;
60 | font-size: 23px;
61 | }
62 |
63 | .send {
64 | width: 30px;
65 | height: 30px;
66 | display: flex;
67 | align-items: center;
68 | justify-content: center;
69 | cursor: pointer;
70 | background: transparent;
71 | border: none;
72 | position: absolute;
73 | bottom: 54px;
74 | right: 11%;
75 | }
76 |
77 |
78 | .send-icon {
79 | width: 33px;
80 | }
81 |
82 | .send-input::placeholder {
83 | color: #828E9E;
84 | font-size: 15px;
85 | }
86 |
87 |
88 | // Mic and animation
89 |
90 | .mic-animation {
91 | font-size: 24px;
92 | transition: transform 0.3s ease;
93 | }
94 |
95 | .mic-animation-listening {
96 | animation: pulse 1s infinite;
97 | }
98 |
99 | @keyframes pulse {
100 | 0% {
101 | transform: scale(1);
102 | color: #ffffff;
103 | }
104 | 50% {
105 | transform: scale(1.2);
106 | color: #ff0000;
107 | }
108 | 100% {
109 | transform: scale(1);
110 | color: #ffffff;
111 | }
112 | }
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | // Product card
121 |
122 | .product-card {
123 | color: white;
124 | width: 100%;
125 | min-height: max-content;
126 | background: #2f2f2f;
127 | padding: 27px;
128 | border-radius: 10px;
129 | img{
130 | width: -webkit-fill-available;
131 | border-radius: 10px;
132 | }
133 | }
134 |
135 | @media screen and (max-width:551px) {
136 | .userMessage {
137 | padding: 10px;
138 | }
139 |
140 | .output {
141 | padding: 10px;
142 | }
143 | .send{
144 | right: 15%;
145 | }
146 | }
--------------------------------------------------------------------------------
/ai/need_analysis_agent.py:
--------------------------------------------------------------------------------
1 | from pydantic import Field
2 | from crewai import Agent
3 | from textwrap import dedent
4 | import json
5 | import re
6 | from typing import Dict
7 |
8 | class NeedAnalysisAgent(Agent):
9 | customer_needs: Dict = Field(default_factory=dict)
10 |
11 | def __init__(self):
12 | super().__init__(
13 | role='Customer Need Analysis Specialist',
14 | goal='Understand the customer’s product needs by asking relevant questions one by one.',
15 | backstory=dedent("""
16 | You are a friendly and patient assistant at an e-commerce store.
17 | Your task is to help customers find the perfect product by asking them questions.
18 | Ask one question at a time and wait for the customer's response before proceeding.
19 | Focus on gathering information that will help in filtering products, such as category, brand, price range, and features.
20 | """),
21 | allow_delegation=False,
22 | verbose=True
23 | )
24 |
25 | def execute_task(self, task, context=None, tools=None, **kwargs):
26 | print("Agent: Hello! I'm here to help you find the perfect product. Could you tell me what you're looking for?")
27 | while True:
28 | user_input = input("You: ")
29 | if user_input.lower() in ['no', "that's all", 'nothing else', 'no more', 'done']:
30 | print("Agent: Thank you for the information!")
31 | break
32 | else:
33 | if 'category' not in self.customer_needs:
34 | self.customer_needs['category'] = user_input
35 | print("Agent: Do you have a preferred brand?")
36 | elif 'brand' not in self.customer_needs:
37 | self.customer_needs['brand'] = user_input
38 | print("Agent: What is your budget or price range?")
39 | elif 'price_range' not in self.customer_needs:
40 | prices = re.findall(r'\d+', user_input.replace(',', ''))
41 | if len(prices) >= 2:
42 | min_price, max_price = map(float, prices[:2])
43 | elif len(prices) == 1:
44 | min_price = 0
45 | max_price = float(prices[0])
46 | else:
47 | min_price = 0
48 | max_price = 1000000 # Default max price
49 | self.customer_needs['price_range'] = [min_price, max_price]
50 | print("Agent: Are there specific features you're looking for?")
51 | elif 'features' not in self.customer_needs:
52 | self.customer_needs['features'] = user_input
53 | print("Agent: Any other preferences? If not, please type 'done'.")
54 | else:
55 | print("Agent: Any other preferences? If not, please type 'done'.")
56 | # Return the customer needs as a JSON string
57 | return json.dumps(self.customer_needs)
58 |
59 | need_analysis_agent = NeedAnalysisAgent()
60 |
--------------------------------------------------------------------------------
/Frontend/README.md:
--------------------------------------------------------------------------------
1 | # Here's our REACT Product recommender AI bot
2 |
3 | ## Here's the Steps to get the code run
4 |
5 |
6 |
7 |
8 | - Clone the Github repository
9 | - Run the command npm-i
10 | - Run the command npm install react-router-dom
11 | - run command npm start
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | # Getting Started with Create React App
25 |
26 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
27 |
28 | ## Available Scripts
29 |
30 | In the project directory, you can run:
31 |
32 | ### `npm start`
33 |
34 | Runs the app in the development mode.\
35 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
36 |
37 | The page will reload when you make changes.\
38 | You may also see any lint errors in the console.
39 |
40 | ### `npm test`
41 |
42 | Launches the test runner in the interactive watch mode.\
43 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
44 |
45 | ### `npm run build`
46 |
47 | Builds the app for production to the `build` folder.\
48 | It correctly bundles React in production mode and optimizes the build for the best performance.
49 |
50 | The build is minified and the filenames include the hashes.\
51 | Your app is ready to be deployed!
52 |
53 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
54 |
55 | ### `npm run eject`
56 |
57 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
58 |
59 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
60 |
61 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
62 |
63 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
64 |
65 | ## Learn More
66 |
67 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
68 |
69 | To learn React, check out the [React documentation](https://reactjs.org/).
70 |
71 | ### Code Splitting
72 |
73 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
74 |
75 | ### Analyzing the Bundle Size
76 |
77 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
78 |
79 | ### Making a Progressive Web App
80 |
81 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
82 |
83 | ### Advanced Configuration
84 |
85 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
86 |
87 | ### Deployment
88 |
89 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
90 |
91 | ### `npm run build` fails to minify
92 |
93 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
94 |
--------------------------------------------------------------------------------
/upload_amazon_data.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import mysql.connector
3 | import sys
4 |
5 | # Conversion rate from INR to USD
6 | INR_TO_USD = 0.012
7 |
8 | # Read the dataset
9 | print("Reading dataset...")
10 | df = pd.read_csv('Amazon-Products.csv', quotechar='"', skipinitialspace=True)
11 |
12 | # Inspect the first few rows to ensure we have loaded the data correctly
13 | print("Inspecting the first few rows of the dataset:")
14 | print(df.head())
15 |
16 | # Remove currency symbols and commas from 'discount_price' and 'actual_price', as well as 'no_of_ratings'
17 | print("Cleaning data...")
18 | df['discount_price'] = df['discount_price'].replace({'₹': '', ',': ''}, regex=True)
19 | df['actual_price'] = df['actual_price'].replace({'₹': '', ',': ''}, regex=True)
20 | df['no_of_ratings'] = df['no_of_ratings'].replace({',': ''}, regex=True)
21 |
22 | # Convert columns to numeric, coercing errors to NaN for incorrect or missing values
23 | df['discount_price'] = pd.to_numeric(df['discount_price'], errors='coerce')
24 | df['actual_price'] = pd.to_numeric(df['actual_price'], errors='coerce')
25 | df['ratings'] = pd.to_numeric(df['ratings'], errors='coerce')
26 | df['no_of_ratings'] = pd.to_numeric(df['no_of_ratings'], errors='coerce')
27 |
28 | # Convert prices from INR to USD
29 | df['discount_price'] = df['discount_price'] * INR_TO_USD
30 | df['actual_price'] = df['actual_price'] * INR_TO_USD
31 |
32 | # Drop rows with NaN values
33 | print("Dropping rows with NaN values...")
34 | df.dropna(inplace=True)
35 |
36 | # Print cleaned data to check the conversion
37 | print("Cleaned data preview:")
38 | print(df[['discount_price', 'actual_price', 'ratings', 'no_of_ratings']].head())
39 | print(df.dtypes)
40 |
41 | # sample 1000 rows
42 | df = df.sample(1000)
43 | print(f"Sampled data shape: {df.shape}")
44 |
45 | # Database connection details
46 | config = {
47 | 'user': 'Users',
48 | 'password': 'AIagents2024Green',
49 | 'host': '34.89.125.152',
50 | 'port': '3306',
51 | 'database': 'product-table',
52 | }
53 |
54 | conn = None
55 | cursor = None
56 | try:
57 | print("Connecting to the database...")
58 | conn = mysql.connector.connect(**config)
59 | cursor = conn.cursor()
60 |
61 | # Create the table if it does not exist
62 | create_table_query = """
63 | CREATE TABLE IF NOT EXISTS amazon_products (
64 | id INT AUTO_INCREMENT PRIMARY KEY,
65 | name VARCHAR(255),
66 | main_category VARCHAR(255),
67 | sub_category VARCHAR(255),
68 | image TEXT,
69 | link TEXT,
70 | ratings FLOAT,
71 | no_of_ratings FLOAT,
72 | discount_price FLOAT,
73 | actual_price FLOAT
74 | );
75 | """
76 | cursor.execute(create_table_query)
77 | print("Table created successfully.")
78 |
79 | # check if any data in the table already, if yes then don't proceed
80 | cursor.execute("SELECT COUNT(*) FROM amazon_products")
81 | count = cursor.fetchone()[0]
82 | if count > 0:
83 | print(f"Table already contains {count} rows. Aborting insertion.")
84 | sys.exit(0)
85 |
86 | # Insert data into the table
87 | print("Inserting data into the table...")
88 | insert_query = """
89 | INSERT INTO amazon_products (name, main_category, sub_category, image, link, ratings, no_of_ratings, discount_price, actual_price)
90 | VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
91 | """
92 | total_rows = df.shape[0]
93 | for i, (_, row) in enumerate(df.iterrows()): # `i` is the iteration counter
94 | cursor.execute(insert_query, (
95 | row['name'],
96 | row['main_category'],
97 | row['sub_category'],
98 | row['image'],
99 | row['link'],
100 | row['ratings'],
101 | row['no_of_ratings'],
102 | row['discount_price'],
103 | row['actual_price']
104 | ))
105 | if i % 100 == 0:
106 | print(f"Progress: {i}/{total_rows} rows inserted ({i/total_rows*100:.2f}%)")
107 |
108 |
109 | conn.commit()
110 | print("Data inserted successfully.")
111 |
112 | except mysql.connector.Error as err:
113 | print(f"Error: {err}")
114 |
115 | finally:
116 | if cursor:
117 | cursor.close()
118 | if conn:
119 | conn.close()
120 | print("Database connection closed.")
121 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Product Recommendation using AI Agents
2 |
3 |
4 | **Introduction**
5 | The AI-Powered Product Recommender System is an innovative application that leverages advanced AI models to provide personalized product recommendations based on natural language user input. By integrating OpenAI's GPT models with a robust backend and interactive frontend, the system offers users an intuitive and engaging shopping experience.
6 |
7 | **Features**
8 | Natural Language Understanding: Users can input queries in natural language, and the system accurately interprets their intent.
9 | Personalized Recommendations: Generates tailored product suggestions based on user preferences, history, and feedback.
10 | User Interaction History: Tracks user interactions to enhance recommendation accuracy over time.
11 | Real-Time Feedback Integration: Allows users to like or dislike products, refining future recommendations.
12 | Scalable Architecture: Built with scalability in mind, suitable for deployment on cloud platforms.
13 | Architecture
14 |
15 |
16 |
17 |
18 | The system comprises the following components:
19 |
20 | **Frontend**: A React.js application that provides an interactive user interface.
21 | **Backend**: A FastAPI server that handles API requests and orchestrates interactions between components.
22 | **AI Agents:**
23 | **NLP Agent**: Processes user input using OpenAI's GPT models to extract intent and preferences.
24 | **Recommendation Agent:** Generates personalized product recommendations.
25 | **Database:** Google Cloud SQL (MySQL) database storing product data, user interactions, and feedback.
26 | **OpenAI API:** Utilized by AI agents for advanced language processing capabilities.
27 |
28 |
29 | **Demo**
30 | Include screenshots or GIFs of your application in action.
31 |
32 | **Technology Stack**
33 | Frontend:
34 | React.js
35 | JavaScript (ES6+)
36 | CSS (or CSS-in-JS libraries)
37 | Backend:
38 | FastAPI
39 | Python 3.9+
40 | MySQL Connector for Python
41 | AI Integration:
42 | OpenAI GPT-3.5 via OpenAI API
43 | Database:
44 | Google Cloud SQL (MySQL)
45 | Hosting and Deployment:
46 | Backend: Google Cloud Run
47 | Frontend: Firebase Hosting
48 | Tools and Services:
49 | Docker
50 | Git and GitHub
51 | Visual Studio Code
52 | Installation
53 | Prerequisites
54 | Node.js (v14 or later)
55 | Python (3.9 or later)
56 | npm (comes with Node.js)
57 | Google Cloud Account with billing enabled
58 | OpenAI API Key
59 | Backend Setup
60 | Clone the Repository
61 |
62 | **How to run the code**
63 |
64 | git clone https://github.com/yourusername/product-recommender-system.git
65 | cd product-recommender-system/backend
66 | Create a Virtual Environment
67 |
68 | 2.
69 | python3 -m venv venv
70 | source venv/bin/activate
71 | Install Dependencies
72 |
73 | 3.
74 | pip install -r requirements.txt
75 | Set Environment Variables
76 |
77 | Create a .env file in the backend directory:
78 |
79 | 4.
80 | DB_USER=your_db_user
81 | DB_PASSWORD=your_db_password
82 | DB_NAME=your_db_name
83 | CLOUD_SQL_CONNECTION_NAME=your_cloud_sql_connection_name
84 | OPENAI_API_KEY=your_openai_api_key
85 | Run the Backend Server
86 |
87 | 5.
88 | uvicorn app.main:app --reload --port 8000
89 | Frontend Setup
90 | Navigate to the Frontend Directory
91 |
92 | 6.
93 | cd ../frontend
94 | Install Dependencies
95 |
96 | 7.
97 | npm install
98 | Set Environment Variables
99 |
100 | Create a .env file in the frontend directory:
101 |
102 | 8.
103 | REACT_APP_API_URL=http://localhost:8000
104 | Run the Frontend Application
105 |
106 | 9.
107 | npm start
108 | AI Agents Setup
109 | Navigate to the AI Agents Directory
110 |
111 | 10.
112 | cd ../ai_agents
113 | Create a Virtual Environment
114 |
115 | 11.
116 | python3 -m venv venv
117 | source venv/bin/activate
118 | Install Dependencies
119 |
120 | 12.
121 | pip install -r requirements.txt
122 | Set Environment Variables
123 |
124 | 13.
125 | OPENAI_API_KEY=your_openai_api_key
126 | Database Setup
127 | Set Up Google Cloud SQL
128 |
129 | 14.
130 | Create a MySQL instance on Google Cloud SQL.
131 | Configure network and authentication.
132 | Initialize the Database
133 |
134 |
135 |
136 | 15.
137 | cd ../scripts/database_setup
138 | python create_tables.py
139 | python seed_data.py
140 | Usage
141 | Access the Application
142 |
143 | 16.
144 | Open your browser and navigate to http://localhost:3000.
145 | Enter a Product Query
146 |
147 | **App Flow:**
148 | Use natural language to describe what you're looking for.
149 | Example: "I'm searching for a waterproof smartwatch under $200 for swimming."
150 | View Recommendations
151 |
152 | The system will display personalized product recommendations based on your input.
153 | Provide Feedback
154 |
155 | Like or dislike products to help the system refine future recommendations.
156 | Explore Products
157 |
158 |
159 | We welcome contributions to enhance the functionality and features of this project. To contribute:
160 |
161 | Fork the Repository
162 |
163 | Click on the "Fork" button at the top right of the repository page.
164 |
165 | Clone Your Fork
166 |
167 | bash
168 | Copy code
169 | git clone https://github.com/yourusername/product-recommender-system.git
170 | Create a Branch
171 |
172 | bash
173 | Copy code
174 | git checkout -b feature/your-feature-name
175 | Make Your Changes
176 |
177 | Follow the existing code style and conventions.
178 | Write clear and concise commit messages.
179 | Push to Your Fork
180 |
181 | bash
182 | Copy code
183 | git add .
184 | git commit -m "Add your commit message here"
185 | git push origin feature/your-feature-name
186 | Create a Pull Request
187 |
188 | Go to the original repository and click on "Pull Requests."
189 | Submit your pull request for review.
190 | License
191 | This project is licensed under the MIT License. See the LICENSE file for details.
192 |
193 | Acknowledgments
194 | OpenAI for providing the GPT models and API access.
195 | Google Cloud Platform for hosting and database services.
196 | Contributors who have helped in developing and improving this project.
197 | Community for support and inspiration.
198 | Feel free to reach out if you have any questions or need assistance with the setup.
199 |
200 |
201 | Discord: russki_boi_vlad
202 |
--------------------------------------------------------------------------------
/Frontend/src/SCSS/Components/_ScreenLoader.scss:
--------------------------------------------------------------------------------
1 | .socket {
2 | width: 200px;
3 | height: 200px;
4 | position: absolute;
5 | left: 50%;
6 | margin-left: -100px;
7 | top: 50%;
8 | margin-top: -100px;
9 | }
10 |
11 | .hex-brick {
12 | background: #000000;
13 | width: 30px;
14 | height: 17px;
15 | position: absolute;
16 | top: 5px;
17 | animation-name: fade00;
18 | animation-duration: 2s;
19 | animation-iteration-count: infinite;
20 | -webkit-animation-name: fade00;
21 | -webkit-animation-duration: 2s;
22 | -webkit-animation-iteration-count: infinite;
23 | }
24 |
25 | .h2 {
26 | transform: rotate(60deg);
27 | -webkit-transform: rotate(60deg);
28 | }
29 |
30 | .h3 {
31 | transform: rotate(-60deg);
32 | -webkit-transform: rotate(-60deg);
33 | }
34 |
35 | .gel {
36 | height: 30px;
37 | width: 30px;
38 | transition: all .3s;
39 | -webkit-transition: all .3s;
40 | position: absolute;
41 | top: 50%;
42 | left: 50%;
43 | }
44 |
45 | .center-gel {
46 | margin-left: -15px;
47 | margin-top: -15px;
48 | animation-name: pulse00;
49 | animation-duration: 2s;
50 | animation-iteration-count: infinite;
51 | -webkit-animation-name: pulse00;
52 | -webkit-animation-duration: 2s;
53 | -webkit-animation-iteration-count: infinite;
54 | }
55 |
56 | .c1 {
57 | margin-left: -47px;
58 | margin-top: -15px;
59 | }
60 |
61 | .c2 {
62 | margin-left: -31px;
63 | margin-top: -43px;
64 | }
65 |
66 | .c3 {
67 | margin-left: 1px;
68 | margin-top: -43px;
69 | }
70 |
71 | .c4 {
72 | margin-left: 17px;
73 | margin-top: -15px;
74 | }
75 |
76 | .c5 {
77 | margin-left: -31px;
78 | margin-top: 13px;
79 | }
80 |
81 | .c6 {
82 | margin-left: 1px;
83 | margin-top: 13px;
84 | }
85 |
86 | .c7 {
87 | margin-left: -63px;
88 | margin-top: -43px;
89 | }
90 |
91 | .c8 {
92 | margin-left: 33px;
93 | margin-top: -43px;
94 | }
95 |
96 | .c9 {
97 | margin-left: -15px;
98 | margin-top: 41px;
99 | }
100 |
101 | .c10 {
102 | margin-left: -63px;
103 | margin-top: 13px;
104 | }
105 |
106 | .c11 {
107 | margin-left: 33px;
108 | margin-top: 13px;
109 | }
110 |
111 | .c12 {
112 | margin-left: -15px;
113 | margin-top: -71px;
114 | }
115 |
116 | .c13 {
117 | margin-left: -47px;
118 | margin-top: -71px;
119 | }
120 |
121 | .c14 {
122 | margin-left: 17px;
123 | margin-top: -71px;
124 | }
125 |
126 | .c15 {
127 | margin-left: -47px;
128 | margin-top: 41px;
129 | }
130 |
131 | .c16 {
132 | margin-left: 17px;
133 | margin-top: 41px;
134 | }
135 |
136 | .c17 {
137 | margin-left: -79px;
138 | margin-top: -15px;
139 | }
140 |
141 | .c18 {
142 | margin-left: 49px;
143 | margin-top: -15px;
144 | }
145 |
146 | .c19 {
147 | margin-left: -63px;
148 | margin-top: -99px;
149 | }
150 |
151 | .c20 {
152 | margin-left: 33px;
153 | margin-top: -99px;
154 | }
155 |
156 | .c21 {
157 | margin-left: 1px;
158 | margin-top: -99px;
159 | }
160 |
161 | .c22 {
162 | margin-left: -31px;
163 | margin-top: -99px;
164 | }
165 |
166 | .c23 {
167 | margin-left: -63px;
168 | margin-top: 69px;
169 | }
170 |
171 | .c24 {
172 | margin-left: 33px;
173 | margin-top: 69px;
174 | }
175 |
176 | .c25 {
177 | margin-left: 1px;
178 | margin-top: 69px;
179 | }
180 |
181 | .c26 {
182 | margin-left: -31px;
183 | margin-top: 69px;
184 | }
185 |
186 | .c27 {
187 | margin-left: -79px;
188 | margin-top: -15px;
189 | }
190 |
191 | .c28 {
192 | margin-left: -95px;
193 | margin-top: -43px;
194 | }
195 |
196 | .c29 {
197 | margin-left: -95px;
198 | margin-top: 13px;
199 | }
200 |
201 | .c30 {
202 | margin-left: 49px;
203 | margin-top: 41px;
204 | }
205 |
206 | .c31 {
207 | margin-left: -79px;
208 | margin-top: -71px;
209 | }
210 |
211 | .c32 {
212 | margin-left: -111px;
213 | margin-top: -15px;
214 | }
215 |
216 | .c33 {
217 | margin-left: 65px;
218 | margin-top: -43px;
219 | }
220 |
221 | .c34 {
222 | margin-left: 65px;
223 | margin-top: 13px;
224 | }
225 |
226 | .c35 {
227 | margin-left: -79px;
228 | margin-top: 41px;
229 | }
230 |
231 | .c36 {
232 | margin-left: 49px;
233 | margin-top: -71px;
234 | }
235 |
236 | .c37 {
237 | margin-left: 81px;
238 | margin-top: -15px;
239 | }
240 |
241 | .r1 {
242 | animation-name: pulse00;
243 | animation-duration: 2s;
244 | animation-iteration-count: infinite;
245 | animation-delay: .2s;
246 | -webkit-animation-name: pulse00;
247 | -webkit-animation-duration: 2s;
248 | -webkit-animation-iteration-count: infinite;
249 | -webkit-animation-delay: .2s;
250 | }
251 |
252 | .r2 {
253 | animation-name: pulse00;
254 | animation-duration: 2s;
255 | animation-iteration-count: infinite;
256 | animation-delay: .4s;
257 | -webkit-animation-name: pulse00;
258 | -webkit-animation-duration: 2s;
259 | -webkit-animation-iteration-count: infinite;
260 | -webkit-animation-delay: .4s;
261 | }
262 |
263 | .r3 {
264 | animation-name: pulse00;
265 | animation-duration: 2s;
266 | animation-iteration-count: infinite;
267 | animation-delay: .6s;
268 | -webkit-animation-name: pulse00;
269 | -webkit-animation-duration: 2s;
270 | -webkit-animation-iteration-count: infinite;
271 | -webkit-animation-delay: .6s;
272 | }
273 |
274 | .r1 > .hex-brick {
275 | animation-name: fade00;
276 | animation-duration: 2s;
277 | animation-iteration-count: infinite;
278 | animation-delay: .2s;
279 | -webkit-animation-name: fade00;
280 | -webkit-animation-duration: 2s;
281 | -webkit-animation-iteration-count: infinite;
282 | -webkit-animation-delay: .2s;
283 | }
284 |
285 | .r2 > .hex-brick {
286 | animation-name: fade00;
287 | animation-duration: 2s;
288 | animation-iteration-count: infinite;
289 | animation-delay: .4s;
290 | -webkit-animation-name: fade00;
291 | -webkit-animation-duration: 2s;
292 | -webkit-animation-iteration-count: infinite;
293 | -webkit-animation-delay: .4s;
294 | }
295 |
296 | .r3 > .hex-brick {
297 | animation-name: fade00;
298 | animation-duration: 2s;
299 | animation-iteration-count: infinite;
300 | animation-delay: .6s;
301 | -webkit-animation-name: fade00;
302 | -webkit-animation-duration: 2s;
303 | -webkit-animation-iteration-count: infinite;
304 | -webkit-animation-delay: .6s;
305 | }
306 |
307 | @keyframes pulse00 {
308 | 0% {
309 | -webkit-transform: scale(1);
310 | transform: scale(1);
311 | }
312 |
313 | 50% {
314 | -webkit-transform: scale(0.01);
315 | transform: scale(0.01);
316 | }
317 |
318 | 100% {
319 | -webkit-transform: scale(1);
320 | transform: scale(1);
321 | }
322 | }
323 |
324 | @keyframes fade00 {
325 | 0% {
326 | background: #252525;
327 | }
328 |
329 | 50% {
330 | background: #000000;
331 | }
332 |
333 | 100% {
334 | background: #353535;
335 | }
336 | }
337 |
--------------------------------------------------------------------------------
/ai/app.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | import openai
3 | import os
4 | from dotenv import load_dotenv
5 | from datetime import datetime
6 | import logging
7 |
8 | # -------------------------
9 | # Configure Logging
10 | # -------------------------
11 | logging.basicConfig(level=logging.INFO)
12 | logger = logging.getLogger(__name__)
13 |
14 | # -------------------------
15 | # Load Environment Variables
16 | # -------------------------
17 | load_dotenv() # Load variables from .env
18 |
19 | # -------------------------
20 | # Configure OpenAI API Key
21 | # -------------------------
22 | openai.api_key = os.getenv("OPENAI_API_KEY")
23 |
24 | # -------------------------
25 | # Streamlit App Layout
26 | # -------------------------
27 | st.set_page_config(
28 | page_title="🛒 Amazon.com Product Recommendation Chatbot",
29 | page_icon=":shopping_cart:",
30 | layout="centered",
31 | )
32 |
33 | st.title("🛒 Amazon.com Product Recommendation Chatbot")
34 | st.write("Hi! I'm here to help you find the perfect products from Amazon.com. Let's get started!")
35 |
36 | # -------------------------
37 | # Initialize Session State
38 | # -------------------------
39 | if 'conversation' not in st.session_state:
40 | st.session_state['conversation'] = [] # To store the conversation history
41 |
42 | # -------------------------
43 | # Define System Prompt
44 | # -------------------------
45 | system_prompt = """
46 | You are a helpful E-commerce Product Recommendation Assistant for Amazon.com. Your job is to assist customers by recommending products from the Amazon.com product catalogue. You will ask at least 6 interactive questions one by one to understand their needs and provide the top 2-3 product recommendations with direct URL links to buy. If a customer asks something relevant to the website or the company, you will provide the customer care email. For unrelated questions, you will politely decline.
47 |
48 | Key Instructions:
49 | - Start by asking what type of product the user is looking for from Amazon.com (e.g., electronics, books, home appliances).
50 | - Ask at least 6 interactive questions one by one without numbering them and make them explicit to the customer.
51 | - Budget.
52 | - Specific preferences (e.g., brand, features, size).
53 | - Usage frequency or purpose.
54 | - Any specific requirements (e.g., color, material).
55 | - Delivery timeframe.
56 | - Any other preferences before recommending products.
57 | - Respond to relevant questions about the website or company by providing the email:
58 | "Please contact our customer care at service@amazon.com for assistance."
59 | - For unrelated questions (e.g., general topics outside of Amazon.com products), respond with:
60 | "Sorry, I can respond only to product-related queries from our company."
61 | - Provide the top 2-3 product recommendations with key features, price, and a direct "Add to Cart" link for each product.
62 | - Offer basic usage instructions if applicable.
63 |
64 | Example Interaction:
65 | User Input: "I need a good face cream for aging skin."
66 |
67 | Your Output:
68 | "What is your budget for the face cream?"
69 | User Input: "Around $50."
70 |
71 | Your Output:
72 | "Do you have any specific concerns like wrinkles or fine lines?"
73 | User Input: "Yes, wrinkles."
74 |
75 | Your Output:
76 | "Would you prefer natural ingredients?"
77 | User Input: "Yes, please."
78 |
79 | Your Output:
80 | "Do you have a brand preference?"
81 | User Input: "No preference."
82 |
83 | Your Output:
84 | "How often do you plan to use this cream?"
85 | User Input: "Twice a day."
86 |
87 | Your Output:
88 | "Any other preferences I should know?"
89 | User Input: "No, that's all."
90 |
91 | Your Output:
92 | "Here are 2 anti-aging creams with natural ingredients under $50:
93 |
94 | 1. **Anti-Aging Cream A** – $48, helps reduce wrinkles and hydrates deeply.
95 | [Add to Cart](https://www.amazon.com/product/anti-aging-cream-a)
96 |
97 | 2. **Anti-Aging Cream B** – $45, natural formula for wrinkle reduction and skin elasticity.
98 | [Add to Cart](https://www.amazon.com/product/anti-aging-cream-b)"
99 |
100 | Provide usage instructions:
101 | "Apply twice daily on clean skin for best results."
102 |
103 | User Input: "Can you help me with shipping information?"
104 |
105 | Your Output:
106 | "Please contact our customer care at service@amazon.com for assistance."
107 |
108 | User Input: "Who won the last soccer world cup?"
109 |
110 | Your Output:
111 | "Sorry, I can respond only to product-related queries from our company."
112 | """
113 |
114 | # -------------------------
115 | # Function to Generate Agent Response
116 | # -------------------------
117 | def generate_agent_response(conversation):
118 | try:
119 | response = openai.ChatCompletion.create(
120 | model="gpt-4",
121 | messages=conversation,
122 | max_tokens=800,
123 | temperature=0.7,
124 | top_p=1,
125 | frequency_penalty=0,
126 | presence_penalty=0,
127 | )
128 | # Corrected access method using attribute access
129 | agent_message = response.choices[0].message['content'].strip()
130 | return agent_message
131 | except openai.error.RateLimitError:
132 | logger.error("OpenAI API Rate Limit Exceeded")
133 | return "**Agent:** Sorry, I'm experiencing high traffic. Please try again later."
134 | except Exception as e:
135 | logger.error(f"OpenAI API Error: {e}")
136 | return f"**Agent:** Sorry, I encountered an error: {e}"
137 |
138 | # -------------------------
139 | # Function to Initialize Conversation
140 | # -------------------------
141 | def initialize_conversation():
142 | st.session_state['conversation'].append({
143 | 'role': 'system',
144 | 'content': system_prompt
145 | })
146 | # Generate the first agent prompt based on the system prompt
147 | agent_response = generate_agent_response(st.session_state['conversation'])
148 | st.session_state['conversation'].append({
149 | 'role': 'assistant',
150 | 'content': agent_response,
151 | 'timestamp': datetime.now().isoformat()
152 | })
153 | logger.info("Initialized conversation with system prompt and first agent response.")
154 |
155 | # -------------------------
156 | # Display Conversation
157 | # -------------------------
158 | def display_conversation():
159 | for message in st.session_state['conversation']:
160 | if message['role'] == 'user':
161 | st.markdown(f"**You:** {message['content']}")
162 | logger.info(f"Displayed User Message: {message['content']}")
163 | elif message['role'] == 'assistant':
164 | st.markdown(f"**Agent:** {message['content']}")
165 | logger.info(f"Displayed Agent Message: {message['content']}")
166 | # Skip messages with role 'system'
167 |
168 | # -------------------------
169 | # Handle User Input and Generate Response
170 | # -------------------------
171 | def handle_input():
172 | user_input = st.session_state['user_input'].strip()
173 | if user_input:
174 | # Append user message to conversation
175 | st.session_state['conversation'].append({
176 | 'role': 'user',
177 | 'content': user_input,
178 | 'timestamp': datetime.now().isoformat()
179 | })
180 | logger.info(f"User: {user_input}")
181 |
182 | # Show spinner while generating response
183 | with st.spinner('Generating recommendations...'):
184 | agent_response = generate_agent_response(st.session_state['conversation'])
185 |
186 | logger.info(f"Agent: {agent_response}")
187 |
188 | # Append agent response to conversation
189 | st.session_state['conversation'].append({
190 | 'role': 'assistant',
191 | 'content': agent_response,
192 | 'timestamp': datetime.now().isoformat()
193 | })
194 |
195 | # Clear user input
196 | st.session_state['user_input'] = ''
197 |
198 | # Rerun to display the new messages
199 | st.experimental_rerun()
200 |
201 | # -------------------------
202 | # Main App Logic
203 | # -------------------------
204 | def main():
205 | # Initialize conversation with system prompt if it's the first run
206 | if len(st.session_state['conversation']) == 0:
207 | initialize_conversation()
208 |
209 | # Display the conversation
210 | st.markdown("### Conversation:")
211 | display_conversation()
212 |
213 | # Input form for user message
214 | st.text_input("You:", key='user_input', on_change=handle_input)
215 |
216 | # Reset Conversation Button
217 | if st.button("Reset Conversation"):
218 | st.session_state['conversation'] = []
219 | st.session_state['user_input'] = ''
220 | logger.info("Conversation reset by user.")
221 | st.experimental_rerun()
222 |
223 | if __name__ == "__main__":
224 | main()
225 |
--------------------------------------------------------------------------------
/Frontend/src/Components/Screen Loader/ScreenLoader.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default function ScreenLoader() {
4 | return (
5 | <>
6 |
7 |
12 |
17 |
22 |
27 |
32 |
37 |
42 |
47 |
52 |
57 |
62 |
67 |
72 |
77 |
82 |
87 |
92 |
97 |
102 |
107 |
112 |
117 |
122 |
127 |
132 |
137 |
142 |
147 |
152 |
157 |
162 |
167 |
172 |
177 |
182 |
187 |
192 |
193 |
194 | >
195 | )
196 | }
197 |
--------------------------------------------------------------------------------
/Frontend/src/Pages/Frontend/BotPage.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useRef, useEffect } from 'react';
2 | import userImg from '../../Assets/user.png';
3 | import bot from "../../Assets/bot.png";
4 | import ResponseLoader from 'Components/Screen Loader/ResponseLoader';
5 | // ------------- Laptop Images ---------------------
6 | import laptop1 from "../../Assets/laptop1.png"
7 | import laptop2 from "../../Assets/laptop2.png"
8 | import laptop3 from "../../Assets/laptop3.png"
9 | import { message } from 'antd';
10 |
11 | export default function BotPage() {
12 |
13 | const [products, setProducts] = useState([]);
14 | const [state, setState] = useState({ text: "" });
15 | const [messages, setMessages] = useState([]);
16 | const [loader, setLoader] = useState(false);
17 | const dummy = useRef();
18 |
19 |
20 | let uid = Math.random().toString().slice(2, 15);
21 |
22 | const handleChange = (e) => setState({ ...state, [e.target.name]: e.target.value });
23 | const handleSubmit = async () => {
24 | if (!state.text) {
25 | message.warning("Enter Prompt")
26 | return;
27 | }
28 | setLoader(true);
29 | setMessages(prevMessages => [...prevMessages, { message: state.text, uid }]);
30 |
31 |
32 | try {
33 | const response = await fetch('https://fakestoreapi.com/products?limit=3');
34 | const result = await response.json();
35 | setProducts(result);
36 | console.log(result)
37 | setMessages(prevMessages => [...prevMessages, result]);
38 | } catch (error) {
39 | console.error('Error fetching prediction:', error);
40 | }
41 | setState({ text: "" });
42 | setLoader(false);
43 |
44 |
45 | };
46 |
47 |
48 | const handleFocus = () => {
49 | document.getElementById("text").style.outline = "none";
50 | };
51 |
52 | // Submit on Enter key
53 |
54 | const handleKeyPress = (e) => {
55 | if (e.key === "Enter" && !e.shiftKey) {
56 | e.preventDefault();
57 | handleSubmit();
58 | }
59 | };
60 |
61 | // For smooth scroll
62 |
63 | useEffect(() => {
64 | dummy.current?.scrollIntoView({ behavior: 'smooth' });
65 | }, [messages]);
66 |
67 | return (
68 |
69 |
70 | Product Recommender
71 |
72 |
73 | {/*
74 | How can I assist you with Product Recomendation?
75 |
*/}
76 | {messages.map((message, i) => {
77 | const className = message.uid ? "userMessage" : "botMessage";
78 | const margin = message.uid ? "ms-auto me-4" : "me-auto ms-4 mb-4";
79 | const text = message.uid ? "text-start" : "text-start";
80 | const img = message.uid ? userImg : "";
81 | const width = message.uid ? "50px" : "90px";
82 | return (
83 |
84 | {message.uid
85 | ?
86 |

87 | :
88 | <>>}
89 |
90 | {/* User message */}
91 |
92 |
93 | {typeof message === 'object' && !Array.isArray(message) ? (
94 | <>
95 | {
96 | message.uid
97 | ?
98 |
99 |
100 | {message.message}
101 |
102 |
103 | :
104 |
105 |
106 | {message.message}
107 |
108 |
109 | }
110 | >
111 | ) : (
112 | message.map((product, idx) => {
113 | return (
114 |
115 |
116 |
{product.title}
117 |
Category:- {product.category}
118 |

119 |
120 |
${product.price}
121 | {product.rating && (
122 |
123 |
124 | Rating: {product.rating.rate.toFixed(1)}
125 | ({product.rating.count} reviews)
126 |
127 |
128 | )}
129 |
130 |
131 |
{product.description}
132 |
133 |
134 | )
135 | })
136 | )}
137 |
138 |
139 |
140 | );
141 | })}
142 |
143 |
144 |
145 |
156 |
157 | {
158 | loader
159 | ?
160 |
161 | :
162 | <>
163 |
187 | >
188 | }
189 |
190 |
191 | );
192 | }
193 |
--------------------------------------------------------------------------------
/ai/app_new.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | import openai
3 | import os
4 | import mysql.connector
5 | from dotenv import load_dotenv
6 | from datetime import datetime
7 | import logging
8 |
9 | # -------------------------
10 | # Configure Logging
11 | # -------------------------
12 | logging.basicConfig(level=logging.INFO)
13 | logger = logging.getLogger(__name__)
14 |
15 | # -------------------------
16 | # Load Environment Variables
17 | # -------------------------
18 | load_dotenv() # Load variables from .env
19 |
20 | # -------------------------
21 | # Configure OpenAI API Key and Database
22 | # -------------------------
23 | openai.api_key = os.getenv("OPENAI_API_KEY")
24 |
25 | db_config = {
26 | 'user': os.getenv('DB_USER'),
27 | 'password': os.getenv('DB_PASSWORD'),
28 | 'host': os.getenv('DB_HOST'),
29 | 'port': os.getenv('DB_PORT'),
30 | 'database': os.getenv('DB_NAME'),
31 | }
32 |
33 | # -------------------------
34 | # Streamlit App Layout
35 | # -------------------------
36 | st.set_page_config(
37 | page_title="🛒 Product Recommendation Chatbot",
38 | page_icon=":shopping_cart:",
39 | layout="centered",
40 | )
41 |
42 | st.title("🛒 Product Recommendation Chatbot")
43 | st.write("Hi! I'm here to help you find the perfect products. Let's get started!")
44 |
45 | # -------------------------
46 | # Initialize Session State
47 | # -------------------------
48 | if 'conversation' not in st.session_state:
49 | st.session_state['conversation'] = [] # To store the conversation history
50 | if 'product_preferences' not in st.session_state:
51 | st.session_state['product_preferences'] = {} # To store user preferences
52 |
53 | # -------------------------
54 | # Define System Prompt
55 | # -------------------------
56 | system_prompt = """
57 | You are an E-commerce Product Recommendation Assistant for an online store. Your role is to engage users through interactive questions to understand their preferences and recommend relevant products from the store's database.
58 |
59 | Ask questions one at a time, and adapt each new question based on the user’s previous responses.
60 | Limit the number of questions to a maximum of 6 in total, focusing on narrowing down the user's specific needs.
61 | After gathering sufficient information, ask the user for confirmation before making a recommendation.
62 | If the user is ready, provide 2-3 product recommendations, each with a direct URL link to purchase.
63 | Always ask: "Shall I recommend some products, or do you have any other preferences?"
64 | If a user asks an unrelated or inappropriate query, politely respond while guiding the conversation back to product recommendations.
65 | Example Flow:
66 |
67 | Assistant: "Hi! Are you looking for any specific type of product today, like electronics, clothing, or something else?"
68 | User: "I’m looking for a laptop."
69 | Assistant: "Great! Do you have any preference for the brand or the operating system?"
70 | User: "I prefer Windows laptops, no specific brand."
71 | Assistant: "Noted. What’s your budget range for the laptop?"
72 | User: "Around $800 to $1000."
73 | Assistant: "Would you like features such as a touch screen or high-end graphics for gaming, or just basic performance for work?"
74 | User: "I need it mainly for work, so performance is more important."
75 | Assistant: "Thanks for the details! Shall I recommend a few options, or would you like to specify any other preferences?"
76 | Once the user confirms, the assistant would respond with:
77 |
78 | Assistant: "Based on your preferences, here are 2-3 laptops that match your needs:
79 |
80 | Laptop A – High-performance laptop for work, 16GB RAM, Windows 11 ($950).
81 | Laptop B – Ultra-slim, 8GB RAM, fast SSD storage, Windows 11 ($890).
82 | Shall I assist you with anything else, or would you like more options?"
83 | """
84 |
85 | # -------------------------
86 | # Function to Query the Database
87 | # -------------------------
88 | def fetch_recommended_products(category, brand, price_range, features):
89 | conn = None
90 | cursor = None
91 | recommendations = []
92 | print(db_config)
93 |
94 | try:
95 | # Establish connection to the database
96 | conn = mysql.connector.connect(**db_config)
97 | cursor = conn.cursor(dictionary=True) # Fetch results as dictionaries
98 |
99 | query = """
100 | SELECT name, discount_price, image, link
101 | FROM amazon_products
102 | WHERE main_category = %s AND sub_category = %s AND discount_price <= %s AND sub_category LIKE %s
103 | LIMIT 3
104 | """
105 | print(category, brand, price_range, features)
106 | print(query)
107 | cursor.execute(query, (category, brand, price_range[1], f"%{features}%"))
108 | recommendations = cursor.fetchall()
109 | print("Recommendations from database: ",recommendations)
110 |
111 | except mysql.connector.Error as err:
112 | logger.error(f"Database error: {err}")
113 | return []
114 |
115 | finally:
116 | if cursor:
117 | cursor.close()
118 | if conn:
119 | conn.close()
120 |
121 | return recommendations
122 |
123 | # -------------------------
124 | # Function to Generate Agent Response
125 | # -------------------------
126 | def generate_agent_response(conversation):
127 | try:
128 | response = openai.ChatCompletion.create(
129 | model="gpt-4",
130 | messages=conversation,
131 | max_tokens=800,
132 | temperature=0.7,
133 | top_p=1,
134 | frequency_penalty=0,
135 | presence_penalty=0,
136 | )
137 | agent_message = response.choices[0].message['content'].strip()
138 | return agent_message
139 | except openai.error.RateLimitError:
140 | logger.error("OpenAI API Rate Limit Exceeded")
141 | return "**Agent:** Sorry, I'm experiencing high traffic. Please try again later."
142 | except Exception as e:
143 | logger.error(f"OpenAI API Error: {e}")
144 | return f"**Agent:** Sorry, I encountered an error: {e}"
145 |
146 | # -------------------------
147 | # Function to Initialize Conversation
148 | # -------------------------
149 | def initialize_conversation():
150 | st.session_state['conversation'].append({
151 | 'role': 'system',
152 | 'content': system_prompt
153 | })
154 | agent_response = "What type of product are you looking for from Amazon.com?"
155 | st.session_state['conversation'].append({
156 | 'role': 'assistant',
157 | 'content': agent_response,
158 | 'timestamp': datetime.now().isoformat()
159 | })
160 | logger.info("Initialized conversation with system prompt and first agent response.")
161 |
162 | # -------------------------
163 | # Display Conversation
164 | # -------------------------
165 | def display_conversation():
166 | for message in st.session_state['conversation']:
167 | if message['role'] == 'user':
168 | st.markdown(f"**You:** {message['content']}")
169 | logger.info(f"Displayed User Message: {message['content']}")
170 | elif message['role'] == 'assistant':
171 | st.markdown(f"**Agent:** {message['content']}")
172 | logger.info(f"Displayed Agent Message: {message['content']}")
173 | # Skip messages with role 'system'
174 |
175 | # -------------------------
176 | # Handle User Input and Generate Response
177 | # -------------------------
178 | def handle_input():
179 | user_input = st.session_state['user_input'].strip()
180 | if user_input:
181 | st.session_state['conversation'].append({
182 | 'role': 'user',
183 | 'content': user_input,
184 | 'timestamp': datetime.now().isoformat()
185 | })
186 | logger.info(f"User: {user_input}")
187 |
188 | agent_response = handle_conversation_logic(user_input)
189 |
190 | # Append agent response to conversation
191 | st.session_state['conversation'].append({
192 | 'role': 'assistant',
193 | 'content': agent_response,
194 | 'timestamp': datetime.now().isoformat()
195 | })
196 |
197 | # Clear user input
198 | st.session_state['user_input'] = ''
199 |
200 | # Rerun to display the new messages
201 | st.experimental_rerun()
202 |
203 | # -------------------------
204 | # Conversation Logic
205 | # -------------------------
206 | def handle_conversation_logic(user_input):
207 | conversation = st.session_state['conversation']
208 |
209 | # Append user input to the conversation
210 | conversation.append({'role': 'user', 'content': user_input})
211 |
212 | # Use OpenAI to generate the next agent response based on user's input and conversation history
213 | agent_response = generate_agent_response(conversation)
214 |
215 | # If the conversation reaches the point of recommending products, use the database
216 | if "recommend" in agent_response.lower():
217 | product_type = st.session_state['product_preferences'].get("product_type", "electronics")
218 | budget = float(st.session_state['product_preferences'].get("budget", 1000))
219 | brand = st.session_state['product_preferences'].get("brand", "Any")
220 | features = st.session_state['product_preferences'].get("features", "")
221 |
222 | recommendations = fetch_recommended_products(product_type, brand, [0, budget], features)
223 |
224 | if recommendations:
225 | product_recommendations = "\n".join([
226 | f"**{prod['product_name']}** – ${prod['price']}, features: {prod['features']}\n[Buy Now]({prod['url']})"
227 | for prod in recommendations
228 | ])
229 | return f"Here are some products that match your preferences:\n{product_recommendations}"
230 | else:
231 | return "Sorry, I couldn't find any products that match your criteria."
232 |
233 | return agent_response
234 |
235 | # -------------------------
236 | # Main App Logic
237 | # -------------------------
238 | def main():
239 | # Initialize conversation with system prompt if it's the first run
240 | if len(st.session_state['conversation']) == 0:
241 | initialize_conversation()
242 |
243 | # Display the conversation
244 | st.markdown("### Conversation:")
245 | display_conversation()
246 |
247 | # Input form for user message
248 | st.text_input("You:", key='user_input', on_change=handle_input)
249 |
250 | # Reset Conversation Button
251 | if st.button("Reset Conversation"):
252 | st.session_state['conversation'] = []
253 | st.session_state['product_preferences'] = {}
254 | st.session_state['user_input'] = ''
255 | logger.info("Conversation reset by user.")
256 | st.experimental_rerun()
257 |
258 | if __name__ == "__main__":
259 | main()
260 |
--------------------------------------------------------------------------------