TestAssistant / app.py
invincible-jha's picture
Update app.py
2f4ecd3 verified
raw
history blame
9.18 kB
import os
import sys
import logging
import gradio as gr
from huggingface_hub import InferenceClient
import re
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
import asyncio
from crewai import Agent, Task, Crew
import random
# Set up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Initialize the client with the Mistral-7B-Instruct-v0.2 model
try:
client = InferenceClient("mistralai/Mistral-7B-Instruct-v0.2")
except Exception as e:
logger.error(f"Failed to initialize InferenceClient: {e}")
sys.exit(1)
# Shared context for both agents
SHARED_CONTEXT = """You are part of a multi-agent system designed to provide respectful, empathetic, and accurate support for Zerodha, a leading Indian financial services company. Your role is crucial in ensuring all interactions uphold the highest standards of customer service while maintaining Zerodha's excellent reputation.
Key points about Zerodha:
1. India's largest discount broker, known for innovative technology and low-cost trading.
2. Flat fee structure: ₹20 per executed order for intraday and F&O trades, zero brokerage for delivery equity investments.
3. Main trading platform: Kite (web and mobile).
4. Coin platform for commission-free direct mutual fund investments.
5. Extensive educational resources through Varsity.
6. Additional tools: Sentinel (price alerts) and ChartIQ (advanced charting).
7. Console for account management and administrative tasks.
Always prioritize user safety, ethical investing practices, and transparent communication. Never provide information that could mislead users or bring disrepute to Zerodha."""
# Guardrail functions (keep these as they were)
# ... (sanitize_input, is_relevant_topic, redact_sensitive_info, check_response_content, check_confidence)
async def generate_response(prompt):
try:
return await client.text_generation(prompt, max_new_tokens=500, temperature=0.7)
except Exception as e:
logger.error(f"Error generating response: {e}")
return "I apologize, but I'm having trouble generating a response at the moment. Please try again later."
def post_process_response(response):
# ... (keep the existing post_process_response function)
# CrewAI setup
communication_expert_crew = Agent(
role='Communication Expert',
goal='Interpret and rephrase user queries with empathy and respect',
backstory="""You are an expert in communication, specializing in understanding and rephrasing queries to ensure they are interpreted in the most positive and constructive light. Your role is crucial in setting the tone for respectful and empathetic interactions.""",
verbose=True,
allow_delegation=False,
tools=[generate_response]
)
response_expert_crew = Agent(
role='Response Expert',
goal='Provide accurate, helpful, and emotionally intelligent responses to user queries',
backstory="""You are an expert in Zerodha's services and policies, with a keen ability to provide comprehensive and empathetic responses. Your role is to ensure that all user queries are addressed accurately while maintaining a respectful and supportive tone.""",
verbose=True,
allow_delegation=False,
tools=[generate_response]
)
# Main function
async def zerodha_support(message, history, username):
try:
sanitized_message = sanitize_input(message)
if not is_relevant_topic(sanitized_message):
return "I'm sorry, but I can only assist with queries related to Zerodha's services and trading. Could you please ask a question about your Zerodha account, trading, or our platforms?"
sanitized_message = redact_sensitive_info(sanitized_message)
# Use crewAI for initial query rephrasing
try:
rephrase_task = Task(
description=f"Rephrase the following user query with empathy and respect: '{sanitized_message}'",
agent=communication_expert_crew
)
crew = Crew(
agents=[communication_expert_crew],
tasks=[rephrase_task],
verbose=2
)
rephrased_query = crew.kickoff()
except Exception as e:
logger.error(f"Error in CrewAI rephrasing: {e}")
rephrased_query = sanitized_message # Fallback to original message if rephrasing fails
# Generate response using Response Expert
response_task = Task(
description=f"Provide an accurate and helpful response to the user query: '{rephrased_query}'",
agent=response_expert_crew
)
crew = Crew(
agents=[response_expert_crew],
tasks=[response_task],
verbose=2
)
response = crew.kickoff()
if not check_response_content(response):
response += "\n\nPlease note that I cannot provide specific investment advice or guarantee returns. For personalized guidance, please consult with a qualified financial advisor."
if not check_confidence(response):
return "I apologize, but I'm not confident in providing an accurate answer to this query. For the most up-to-date and accurate information, please contact Zerodha's customer support directly."
final_response = post_process_response(response)
return final_response
except Exception as e:
logger.error(f"Error in zerodha_support: {e}")
return "I apologize, but an error occurred while processing your request. Please try again later."
# Custom CSS for better styling
custom_css = """
.container {
max-width: 800px;
margin: auto;
padding: 20px;
}
.title {
text-align: center;
color: #387EF5;
font-size: 32px;
margin-bottom: 20px;
}
.description {
text-align: center;
color: #555;
margin-bottom: 30px;
}
.chatbot {
border: 1px solid #ddd;
border-radius: 10px;
overflow: hidden;
}
.user-info {
background-color: #f0f0f0;
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
}
"""
# Placeholder function for user authentication (you'd implement this with your backend)
def authenticate(username, password):
# This is a mock authentication. In a real scenario, you'd verify against a database.
return username == "demo" and password == "password"
# Function to generate a random support ticket number
def generate_ticket_number():
return f"ZRD-{random.randint(100000, 999999)}"
# Gradio interface setup
with gr.Blocks(css=custom_css) as demo:
gr.HTML("<div class='title'>Zerodha Support Assistant</div>")
gr.HTML("<div class='description'>Ask questions about Zerodha's services, trading, account management, and more.</div>")
with gr.Tab("Login"):
username_input = gr.Textbox(label="Username")
password_input = gr.Textbox(label="Password", type="password")
login_button = gr.Button("Login")
login_message = gr.Textbox(label="Login Status", interactive=False)
with gr.Tab("Support Chat"):
with gr.Row():
with gr.Column(scale=2):
chatbot = gr.Chatbot(height=400)
message_input = gr.Textbox(label="Your Message", placeholder="Type your question here...")
submit_button = gr.Button("Send")
with gr.Column(scale=1):
with gr.Box():
gr.HTML("<div class='user-info'>")
user_display = gr.Textbox(label="Logged in as", interactive=False)
ticket_number = gr.Textbox(label="Support Ticket", value=generate_ticket_number(), interactive=False)
gr.HTML("</div>")
gr.HTML("<h4>Quick Links</h4>")
gr.HTML("<ul><li><a href='https://zerodha.com/varsity/' target='_blank'>Zerodha Varsity</a></li><li><a href='https://console.zerodha.com/' target='_blank'>Zerodha Console</a></li></ul>")
# Example queries
gr.Examples(
examples=[
"How do I open a Zerodha account?",
"What are the brokerage charges for intraday trading?",
"How can I withdraw funds from my Zerodha account?",
"What is the margin requirement for F&O trading?",
"How do I use the Kite mobile app?",
],
inputs=message_input,
)
# Login logic
def login(username, password):
if authenticate(username, password):
return "Login successful!", gr.Tabs.update(selected="Support Chat"), username
else:
return "Login failed. Please try again.", gr.Tabs.update(selected="Login"), ""
login_button.click(login, inputs=[username_input, password_input], outputs=[login_message, demo.tabs, user_display])
# Chat logic
submit_button.click(zerodha_support, inputs=[message_input, chatbot, user_display], outputs=chatbot)
message_input.submit(zerodha_support, inputs=[message_input, chatbot, user_display], outputs=chatbot)
if __name__ == "__main__":
demo.launch()