krinya commited on
Commit
4fd28e1
Β·
1 Parent(s): 6bd3e57

Add Gradio and Streamlit chat interfaces for Sales Assistant

Browse files

- Created `run_ui.sh` script to launch the UI applications.
- Added README documentation for the Sales Assistant Chat UI, detailing available interfaces, quick start instructions, example queries, features, technical details, prerequisites, troubleshooting, and development tips.
- Implemented Gradio chat interface in `gradio_app.py` with features for product search, quote generation, and data analysis.
- Developed Streamlit chat interface in `streamlit_app.py` with similar functionalities and enhanced user interaction features.

.gitignore CHANGED
@@ -91,4 +91,7 @@ Thumbs.db
91
 
92
  # Temporary files
93
  *.tmp
94
- *.temp
 
 
 
 
91
 
92
  # Temporary files
93
  *.tmp
94
+ *.temp
95
+
96
+ # Quotes
97
+ src/sales_assistant/created_quotes/*
pyproject.toml CHANGED
@@ -17,11 +17,12 @@ dependencies = [
17
  "langchain>=0.3.27",
18
  "langgraph>=0.6.5",
19
  "langchain-openai>=0.3.30",
20
- "langchain-nvidia-ai-endpoints>=0.3.0",
21
  "langsmith>=0.2.13",
22
  "pydantic>=2.11.7",
23
  "huggingface-hub>=0.34.4",
24
  "langchain-huggingface>=0.3.1",
 
 
25
  ]
26
 
27
  [build-system]
 
17
  "langchain>=0.3.27",
18
  "langgraph>=0.6.5",
19
  "langchain-openai>=0.3.30",
 
20
  "langsmith>=0.2.13",
21
  "pydantic>=2.11.7",
22
  "huggingface-hub>=0.34.4",
23
  "langchain-huggingface>=0.3.1",
24
+ "gradio>=5.43.1",
25
+ "streamlit>=1.48.1",
26
  ]
27
 
28
  [build-system]
src/sales_assistant/agent_main/agent_node.py CHANGED
@@ -9,6 +9,7 @@ from langgraph.graph import MessagesState
9
  from langchain_openai import ChatOpenAI
10
  from dotenv import load_dotenv
11
  from ..prompts.system_prompt import SYSTEM_PROMPT
 
12
 
13
  # Load environment variables
14
  load_dotenv()
@@ -51,8 +52,6 @@ def agent_node(state: MessagesState) -> Dict[str, Any]:
51
  api_key=os.getenv("OPENAI_API_KEY"),
52
  )
53
 
54
- # Bind tools to the model
55
- from .tools_node import get_all_tools
56
  tools = get_all_tools()
57
  model_with_tools = model.bind_tools(tools)
58
 
 
9
  from langchain_openai import ChatOpenAI
10
  from dotenv import load_dotenv
11
  from ..prompts.system_prompt import SYSTEM_PROMPT
12
+ from .tools_node import get_all_tools
13
 
14
  # Load environment variables
15
  load_dotenv()
 
52
  api_key=os.getenv("OPENAI_API_KEY"),
53
  )
54
 
 
 
55
  tools = get_all_tools()
56
  model_with_tools = model.bind_tools(tools)
57
 
src/sales_assistant/ui_dashboard/README.md ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Sales Assistant Chat UI
2
+
3
+ This directory contains two different chat interfaces for the Sales Assistant:
4
+
5
+ ## 🎨 Available Interfaces
6
+
7
+ ### 1. Gradio Chat Interface (`gradio_app.py`)
8
+ - **URL**: http://localhost:7860
9
+ - **Features**:
10
+ - Simple, clean chat interface
11
+ - Example queries sidebar
12
+ - Real-time responses
13
+ - Mobile-friendly design
14
+ - **Best for**: Quick testing and development
15
+
16
+ ### 2. Streamlit Chat Interface (`streamlit_app.py`)
17
+ - **URL**: http://localhost:8501
18
+ - **Features**:
19
+ - Rich sidebar with capabilities overview
20
+ - Chat statistics
21
+ - Agent status monitoring
22
+ - Professional dashboard layout
23
+ - **Best for**: Demos and production use
24
+
25
+ ## πŸš€ Quick Start
26
+
27
+ ### Option 1: Use the Launcher Script
28
+ ```bash
29
+ # From the project root
30
+ ./run_ui.sh
31
+ ```
32
+
33
+ ### Option 2: Run Individual Apps
34
+
35
+ **Gradio:**
36
+ ```bash
37
+ uv run python src/sales_assistant/ui_dashboard/gradio_app.py
38
+ ```
39
+
40
+ **Streamlit:**
41
+ ```bash
42
+ uv run streamlit run src/sales_assistant/ui_dashboard/streamlit_app.py --server.port 8501
43
+ ```
44
+
45
+ ### Option 3: Run Both Simultaneously
46
+ ```bash
47
+ # Terminal 1 - Gradio
48
+ uv run python src/sales_assistant/ui_dashboard/gradio_app.py
49
+
50
+ # Terminal 2 - Streamlit
51
+ uv run streamlit run src/sales_assistant/ui_dashboard/streamlit_app.py --server.port 8501
52
+ ```
53
+
54
+ ## πŸ’‘ Example Queries
55
+
56
+ Try these sample queries in either interface:
57
+
58
+ - `"Show me information about our products"`
59
+ - `"I need a quote for industrial equipment"`
60
+ - `"What are the current exchange rates?"`
61
+ - `"Find products with price under $1000"`
62
+ - `"Generate a quote for customer 'Tech Solutions Inc'"`
63
+ - `"Show me Samsung outdoor TVs"`
64
+
65
+ ## πŸ”§ Features
66
+
67
+ Both interfaces provide access to:
68
+
69
+ - **Product Database Search**: Explore the complete product catalog
70
+ - **Quote Generation**: Create professional quotes with current pricing
71
+ - **Data Analysis**: Get statistical insights about products
72
+ - **Exchange Rates**: Current currency conversion information
73
+ - **Natural Language Processing**: Ask questions in plain English
74
+
75
+ ## πŸ›  Technical Details
76
+
77
+ - **Backend**: LangGraph-based conversational agent
78
+ - **Database**: MySQL with SSH tunnel connection
79
+ - **AI Models**: OpenAI GPT models with tool calling
80
+ - **State Management**: Persistent conversation history
81
+ - **Tracing**: Optional LangSmith integration for debugging
82
+
83
+ ## πŸ“‹ Prerequisites
84
+
85
+ Make sure you have:
86
+
87
+ 1. **Environment Variables** set in `.env`:
88
+ - `OPENAI_API_KEY`
89
+ - `MODEL_PROVIDER=openai`
90
+ - `MODEL_NAME=gpt-4`
91
+ - `MYSQL_HOST`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DB`
92
+ - Optional: `LANGSMITH_API_KEY`, `LANGSMITH_PROJECT`
93
+
94
+ 2. **Dependencies** installed:
95
+ ```bash
96
+ uv add gradio streamlit
97
+ ```
98
+
99
+ 3. **Database Access**: Ensure your MySQL database is accessible and the SSH tunnel is configured if needed.
100
+
101
+ ## πŸ” Troubleshooting
102
+
103
+ ### Common Issues:
104
+
105
+ 1. **Agent Initialization Failed**
106
+ - Check your `.env` file configuration
107
+ - Verify database connectivity
108
+ - Ensure all required environment variables are set
109
+
110
+ 2. **Port Already in Use**
111
+ - Change ports in the launch commands
112
+ - Kill existing processes: `pkill -f "gradio_app\|streamlit"`
113
+
114
+ 3. **Database Connection Issues**
115
+ - Verify SSH tunnel configuration
116
+ - Check database credentials
117
+ - Ensure the database server is running
118
+
119
+ ### Logs and Debugging:
120
+
121
+ - Both apps print initialization status to the console
122
+ - Database queries are logged with SQL statements
123
+ - LangSmith tracing can be enabled for detailed debugging
124
+
125
+ ## 🎯 Development Tips
126
+
127
+ - **Hot Reload**: Streamlit supports hot reload for development
128
+ - **Custom Styling**: Both apps support custom CSS/themes
129
+ - **Configuration**: Modify the `ConversationConfig` for different settings
130
+ - **Extensions**: Easy to add new features through the agent tools system
src/sales_assistant/ui_dashboard/gradio_app.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Gradio Chat UI for Sales Assistant
3
+
4
+ This module provides a simple Gradio-based chat interface for the sales assistant.
5
+ """
6
+ import os
7
+ import sys
8
+ import gradio as gr
9
+ from typing import List, Tuple, Dict
10
+
11
+ # Add the src directory to the path
12
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
13
+
14
+ from sales_assistant.main import (
15
+ check_environment_setup,
16
+ create_custom_config
17
+ )
18
+ from sales_assistant.agent_main.agent_runner import (
19
+ create_agent_runner,
20
+ run_conversation_turn
21
+ )
22
+
23
+
24
+ class SalesAssistantChat:
25
+ """Chat interface for the sales assistant."""
26
+
27
+ def __init__(self):
28
+ """Initialize the chat interface."""
29
+ self.compiled_graph = None
30
+ self.checkpointer = None
31
+ self.langsmith_client = None
32
+ self.thread_id = None
33
+ self.initialize_agent()
34
+
35
+ def initialize_agent(self):
36
+ """Initialize the agent runner."""
37
+ try:
38
+ # Check environment setup
39
+ if not check_environment_setup():
40
+ print("❌ Environment setup failed")
41
+ return
42
+
43
+ # Create configuration
44
+ config = create_custom_config(
45
+ session_id="gradio_session",
46
+ user_id="gradio_user",
47
+ enable_langsmith=True
48
+ )
49
+
50
+ # Create agent runner
51
+ self.compiled_graph, self.checkpointer, self.langsmith_client, self.thread_id = create_agent_runner(config)
52
+ print("βœ… Sales Assistant initialized successfully!")
53
+
54
+ except Exception as e:
55
+ print(f"❌ Failed to initialize sales assistant: {e}")
56
+ self.compiled_graph = None
57
+
58
+ def chat_function(self, message: str, history: List[Dict[str, str]]) -> Tuple[str, List[Dict[str, str]]]:
59
+ """
60
+ Process a chat message and return the response.
61
+
62
+ Args:
63
+ message: User's input message
64
+ history: Chat history as list of message dictionaries
65
+
66
+ Returns:
67
+ Tuple of (empty_string, updated_history)
68
+ """
69
+ if not self.compiled_graph:
70
+ error_response = "❌ Sales Assistant is not properly initialized. Please check your environment configuration."
71
+ history.append({"role": "user", "content": message})
72
+ history.append({"role": "assistant", "content": error_response})
73
+ return "", history
74
+
75
+ try:
76
+ # Run conversation turn
77
+ response = run_conversation_turn(
78
+ compiled_graph=self.compiled_graph,
79
+ thread_id=self.thread_id,
80
+ user_input=message,
81
+ langsmith_client=self.langsmith_client
82
+ )
83
+
84
+ # Add to history
85
+ history.append({"role": "user", "content": message})
86
+ history.append({"role": "assistant", "content": response})
87
+
88
+ except Exception as e:
89
+ error_response = f"❌ Error processing your request: {str(e)}"
90
+ history.append({"role": "user", "content": message})
91
+ history.append({"role": "assistant", "content": error_response})
92
+
93
+ return "", history
94
+
95
+
96
+ def create_gradio_interface():
97
+ """Create and configure the Gradio interface."""
98
+
99
+ # Initialize the chat assistant
100
+ chat_assistant = SalesAssistantChat()
101
+
102
+ # Create the interface
103
+ with gr.Blocks(
104
+ title="Sales Assistant with Quote Generation",
105
+ theme=gr.themes.Soft(),
106
+ css="""
107
+ .gradio-container {
108
+ max-width: 1200px !important;
109
+ }
110
+ """
111
+ ) as interface:
112
+
113
+ gr.Markdown(
114
+ """
115
+ # πŸ€– Sales Assistant with Quote Generation
116
+
117
+ Welcome to the Sales Assistant! I can help you:
118
+ - πŸ” Search and explore our product database
119
+ - πŸ“Š Analyze product data and statistics
120
+ - πŸ’° Generate detailed quotes with pricing
121
+ - 🌍 Provide exchange rate information
122
+ - ❓ Answer questions about our products and services
123
+
124
+ Simply type your question or request below to get started!
125
+ """
126
+ )
127
+
128
+ # Chat interface
129
+ chatbot = gr.Chatbot(
130
+ value=[],
131
+ height=500,
132
+ label="Sales Assistant Chat",
133
+ show_label=True,
134
+ avatar_images=("πŸ‘€", "πŸ€–"),
135
+ type="messages"
136
+ )
137
+
138
+ # Input components
139
+ with gr.Row():
140
+ msg_input = gr.Textbox(
141
+ placeholder="Ask me about products, request a quote, or explore our database...",
142
+ label="Your Message",
143
+ scale=4,
144
+ lines=1
145
+ )
146
+ send_btn = gr.Button("Send", variant="primary", scale=1)
147
+
148
+ # Example queries
149
+ with gr.Row():
150
+ gr.Examples(
151
+ examples=[
152
+ "Show me information about our products",
153
+ "I need a quote for industrial equipment",
154
+ "What are the current exchange rates?",
155
+ "Find products with price under $1000",
156
+ "Generate a quote for customer 'Tech Solutions Inc'",
157
+ "Show me product statistics"
158
+ ],
159
+ inputs=msg_input,
160
+ label="Example Queries"
161
+ )
162
+
163
+ # Additional information
164
+ with gr.Accordion("ℹ️ About This Assistant", open=False):
165
+ gr.Markdown(
166
+ """
167
+ This Sales Assistant is powered by advanced AI and has access to:
168
+
169
+ - **Product Database**: Complete catalog with specifications and pricing
170
+ - **Quote Generation**: Professional quote creation with current exchange rates
171
+ - **Data Analysis**: Statistical insights and product comparisons
172
+ - **Real-time Information**: Current pricing and availability
173
+
174
+ The assistant uses natural language processing to understand your requests
175
+ and can perform complex database queries to provide accurate information.
176
+ """
177
+ )
178
+
179
+ # Event handlers
180
+ def submit_message(message, history):
181
+ return chat_assistant.chat_function(message, history)
182
+
183
+ # Wire up the events
184
+ msg_input.submit(
185
+ submit_message,
186
+ inputs=[msg_input, chatbot],
187
+ outputs=[msg_input, chatbot]
188
+ )
189
+
190
+ send_btn.click(
191
+ submit_message,
192
+ inputs=[msg_input, chatbot],
193
+ outputs=[msg_input, chatbot]
194
+ )
195
+
196
+ return interface
197
+
198
+
199
+ def main():
200
+ """Main function to run the Gradio app."""
201
+ print("πŸš€ Starting Gradio Sales Assistant...")
202
+
203
+ # Create interface
204
+ interface = create_gradio_interface()
205
+
206
+ # Launch the app
207
+ interface.launch(
208
+ server_name="0.0.0.0",
209
+ server_port=7860,
210
+ share=False,
211
+ show_error=True
212
+ )
213
+
214
+
215
+ if __name__ == "__main__":
216
+ main()
src/sales_assistant/ui_dashboard/streamlit_app.py ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Streamlit Chat UI for Sales Assistant
3
+
4
+ This module provides a simple Streamlit-based chat interface for the sales assistant.
5
+ """
6
+ import os
7
+ import sys
8
+ import streamlit as st
9
+ from typing import Dict, Any, List
10
+
11
+ # Add the src directory to the path
12
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
13
+
14
+ from sales_assistant.main import (
15
+ check_environment_setup,
16
+ create_custom_config
17
+ )
18
+ from sales_assistant.agent_main.agent_runner import (
19
+ create_agent_runner,
20
+ run_conversation_turn
21
+ )
22
+
23
+
24
+ # Page configuration
25
+ st.set_page_config(
26
+ page_title="Sales Assistant with Quote Generation",
27
+ page_icon="πŸ€–",
28
+ layout="wide",
29
+ initial_sidebar_state="expanded"
30
+ )
31
+
32
+
33
+ def initialize_session_state():
34
+ """Initialize Streamlit session state variables."""
35
+ if "messages" not in st.session_state:
36
+ st.session_state.messages = []
37
+
38
+ if "compiled_graph" not in st.session_state:
39
+ st.session_state.compiled_graph = None
40
+
41
+ if "checkpointer" not in st.session_state:
42
+ st.session_state.checkpointer = None
43
+
44
+ if "langsmith_client" not in st.session_state:
45
+ st.session_state.langsmith_client = None
46
+
47
+ if "thread_id" not in st.session_state:
48
+ st.session_state.thread_id = None
49
+
50
+ if "agent_initialized" not in st.session_state:
51
+ st.session_state.agent_initialized = False
52
+
53
+
54
+ def initialize_agent():
55
+ """Initialize the sales assistant agent."""
56
+ if st.session_state.agent_initialized:
57
+ return True
58
+
59
+ try:
60
+ with st.spinner("Initializing Sales Assistant..."):
61
+ # Check environment setup
62
+ if not check_environment_setup():
63
+ st.error("❌ Environment setup failed. Please check your configuration.")
64
+ return False
65
+
66
+ # Create configuration
67
+ config = create_custom_config(
68
+ session_id="streamlit_session",
69
+ user_id="streamlit_user",
70
+ enable_langsmith=True
71
+ )
72
+
73
+ # Create agent runner
74
+ compiled_graph, checkpointer, langsmith_client, thread_id = create_agent_runner(config)
75
+
76
+ # Store in session state
77
+ st.session_state.compiled_graph = compiled_graph
78
+ st.session_state.checkpointer = checkpointer
79
+ st.session_state.langsmith_client = langsmith_client
80
+ st.session_state.thread_id = thread_id
81
+ st.session_state.agent_initialized = True
82
+
83
+ st.success("βœ… Sales Assistant initialized successfully!")
84
+ return True
85
+
86
+ except Exception as e:
87
+ st.error(f"❌ Failed to initialize sales assistant: {e}")
88
+ return False
89
+
90
+
91
+ def display_sidebar():
92
+ """Display the sidebar with information and controls."""
93
+ with st.sidebar:
94
+ st.markdown("# πŸ€– Sales Assistant")
95
+ st.markdown("---")
96
+
97
+ # Status indicator
98
+ if st.session_state.agent_initialized:
99
+ st.success("🟒 Agent Online")
100
+ else:
101
+ st.error("πŸ”΄ Agent Offline")
102
+
103
+ st.markdown("---")
104
+
105
+ # Information section
106
+ st.markdown("### πŸ”§ Capabilities")
107
+ st.markdown("""
108
+ - πŸ” **Product Search**: Find products by criteria
109
+ - πŸ“Š **Data Analysis**: Statistical insights
110
+ - πŸ’° **Quote Generation**: Professional quotes
111
+ - 🌍 **Exchange Rates**: Current currency rates
112
+ - πŸ“ˆ **Database Insights**: Explore product data
113
+ """)
114
+
115
+ st.markdown("---")
116
+
117
+ # Example queries
118
+ st.markdown("### πŸ’‘ Example Queries")
119
+ example_queries = [
120
+ "Show me product information",
121
+ "Generate a quote for equipment",
122
+ "What are current exchange rates?",
123
+ "Find products under $1000",
124
+ "Show product statistics"
125
+ ]
126
+
127
+ for query in example_queries:
128
+ if st.button(query, key=f"example_{hash(query)}", use_container_width=True):
129
+ st.session_state.messages.append({"role": "user", "content": query})
130
+ st.rerun()
131
+
132
+ st.markdown("---")
133
+
134
+ # Clear chat button
135
+ if st.button("πŸ—‘οΈ Clear Chat", use_container_width=True):
136
+ st.session_state.messages = []
137
+ st.rerun()
138
+
139
+ # Restart agent button
140
+ if st.button("πŸ”„ Restart Agent", use_container_width=True):
141
+ st.session_state.agent_initialized = False
142
+ st.session_state.compiled_graph = None
143
+ st.session_state.checkpointer = None
144
+ st.session_state.langsmith_client = None
145
+ st.session_state.thread_id = None
146
+ st.rerun()
147
+
148
+
149
+ def display_chat_messages():
150
+ """Display the chat messages."""
151
+ for message in st.session_state.messages:
152
+ with st.chat_message(message["role"]):
153
+ st.markdown(message["content"])
154
+
155
+
156
+ def process_user_input(user_input: str) -> str:
157
+ """
158
+ Process user input and get response from the sales assistant.
159
+
160
+ Args:
161
+ user_input: The user's message
162
+
163
+ Returns:
164
+ The assistant's response
165
+ """
166
+ if not st.session_state.compiled_graph:
167
+ return "❌ Sales Assistant is not properly initialized. Please restart the agent."
168
+
169
+ try:
170
+ # Run conversation turn
171
+ response = run_conversation_turn(
172
+ compiled_graph=st.session_state.compiled_graph,
173
+ thread_id=st.session_state.thread_id,
174
+ user_input=user_input,
175
+ langsmith_client=st.session_state.langsmith_client
176
+ )
177
+ return response
178
+
179
+ except Exception as e:
180
+ return f"❌ Error processing your request: {str(e)}"
181
+
182
+
183
+ def main():
184
+ """Main Streamlit application."""
185
+ # Initialize session state
186
+ initialize_session_state()
187
+
188
+ # Main title
189
+ st.title("πŸ€– Sales Assistant with Quote Generation")
190
+ st.markdown("---")
191
+
192
+ # Initialize agent if not done
193
+ if not st.session_state.agent_initialized:
194
+ if not initialize_agent():
195
+ st.stop()
196
+
197
+ # Display sidebar
198
+ display_sidebar()
199
+
200
+ # Main chat area
201
+ col1, col2 = st.columns([3, 1])
202
+
203
+ with col1:
204
+ # Introduction message
205
+ if not st.session_state.messages:
206
+ st.markdown("""
207
+ ### Welcome to the Sales Assistant! πŸ‘‹
208
+
209
+ I'm here to help you with:
210
+ - πŸ” **Product Information**: Search and explore our product database
211
+ - πŸ“Š **Data Analysis**: Get insights and statistics about products
212
+ - πŸ’° **Quote Generation**: Create professional quotes with current pricing
213
+ - 🌍 **Exchange Rates**: Get up-to-date currency information
214
+ - ❓ **General Questions**: Ask me anything about our products and services
215
+
216
+ **To get started**, type your question in the chat box below or click one of the example queries in the sidebar.
217
+ """)
218
+ st.markdown("---")
219
+
220
+ # Display chat messages
221
+ display_chat_messages()
222
+
223
+ # Chat input
224
+ if prompt := st.chat_input("Ask me about products, request a quote, or explore our database..."):
225
+ # Add user message to chat history
226
+ st.session_state.messages.append({"role": "user", "content": prompt})
227
+
228
+ # Display user message
229
+ with st.chat_message("user"):
230
+ st.markdown(prompt)
231
+
232
+ # Get and display assistant response
233
+ with st.chat_message("assistant"):
234
+ with st.spinner("Thinking..."):
235
+ response = process_user_input(prompt)
236
+ st.markdown(response)
237
+
238
+ # Add assistant response to chat history
239
+ st.session_state.messages.append({"role": "assistant", "content": response})
240
+
241
+ with col2:
242
+ # Stats section
243
+ st.markdown("### πŸ“Š Chat Statistics")
244
+ total_messages = len(st.session_state.messages)
245
+ user_messages = len([m for m in st.session_state.messages if m["role"] == "user"])
246
+ assistant_messages = len([m for m in st.session_state.messages if m["role"] == "assistant"])
247
+
248
+ st.metric("Total Messages", total_messages)
249
+ st.metric("Your Messages", user_messages)
250
+ st.metric("Assistant Responses", assistant_messages)
251
+
252
+ # Recent activity
253
+ if st.session_state.messages:
254
+ st.markdown("### πŸ•’ Recent Activity")
255
+ recent_messages = st.session_state.messages[-3:]
256
+ for msg in recent_messages:
257
+ role_icon = "πŸ‘€" if msg["role"] == "user" else "πŸ€–"
258
+ st.text(f"{role_icon} {msg['content'][:50]}...")
259
+
260
+ # Footer
261
+ st.markdown("---")
262
+ st.markdown(
263
+ """
264
+ <div style='text-align: center; color: #666;'>
265
+ Sales Assistant powered by AI | Built with Streamlit
266
+ </div>
267
+ """,
268
+ unsafe_allow_html=True
269
+ )
270
+
271
+
272
+ if __name__ == "__main__":
273
+ main()
uv.lock CHANGED
The diff for this file is too large to render. See raw diff