RSNROXX/virtual_banking_assistant
0
1# 1. IMPORT LIBRARIES2import os3import json4import random5from openai import OpenAI6import gradio as gr7 8# 2. SETUP CLIENT9 10# Fetch key from secure cloud secrets11api_key = os.environ.get("GROQ_API_KEY")12 13client = OpenAI(14 base_url = 'https://api.groq.com/openai/v1',15 api_key = api_key 16)17 18 19# UPDATES ARE REQUIRED IN THE FOLLOWING SECTIONS:20# 3. MOCK DATABASE <-- ADDED TRANSACTIONS, CARD STATUS, COMPLAINTS21# 4. TOOLKIT <-- ADDED NEW TOOLS/FUNCTION CALLS22# 5. TOOL SCHEMA <-- ADDED SCHEMA FOR THE NEW TOOLS23# 6. SYSTEM INSTRUCTION <-- ADDED NEW RULES FOR LANGUAGE AND ESCALAITON (AGENT/HUMAN ASSISTANCE). ALSO MODIFIED RULES FOR RECOMMENDATIONS BASED ON BALANCE. 24 25# --- THE 'BRAIN' ALMOST REMAINS THE SAME, JUST ADDED MORE TOOLS BELOW. ---26 27 28# 3. EXPANDED MOCK DATABASE (Added Transactions & Card Status)29users_db = {30 "user_123": {31 "name": "Amit Sharma", 32 "balance": 150000, 33 "currency": "₹",34 "loans": "Eligible for Personal Loan up to ₹5 Lakhs",35 "card_status": "Active", # Can be 'Active' or 'Blocked'36 "transactions": [37 {"date": "2025-10-01", "desc": "Salary Credited", "amount": 80000},38 {"date": "2025-10-03", "desc": "Netflix Subscription", "amount": -649},39 {"date": "2025-10-05", "desc": "Uber Ride", "amount": -450},40 {"date": "2025-10-10", "desc": "Amazon Purchase", "amount": -12000},41 {"date": "2025-10-12", "desc": "Starbucks", "amount": -800}42 ],43 "complaints": [] # To store complain tickets44 }45}46 47# 4. EXPANDED TOOLKIT (The New Capabilities) 48 49def get_balance(user_id):50 if user_id in users_db:51 return json.dumps({52 "name": users_db[user_id]["name"],53 "balance": users_db[user_id]["balance"],54 "card_status": users_db[user_id]["card_status"]55 })56 return json.dumps({"error": "User not found"})57 58def get_transactions(user_id):59 """Returns last 5 transactions.""" #<-- docstring for AI60 if user_id in users_db:61 txns = users_db[user_id]["transactions"][-5:] # Get last 562 return json.dumps({"history": txns})63 return json.dumps({"error": "User not found"})64 65def manage_card(user_id, action):66 """Blocks or Unblocks a card.""" # <-- docstring for AI67 if user_id in users_db:68 current_status = users_db[user_id]["card_status"]69 if action.lower() == "block":70 users_db[user_id]["card_status"] = "Blocked"71 return json.dumps({"status": "Success", "message": "Card has been BLOCKED immediately."})72 elif action.lower() == "unblock":73 users_db[user_id]["card_status"] = "Active"74 return json.dumps({"status": "Success", "message": "Card is now ACTIVE."})75 return json.dumps({"error": "User not found"})76 77def raise_complaint(user_id, issue):78 """Logs a complaint and returns a ticket ID.""" # <--docstring for AI 79 ticket_id = f"TKT-{random.randint(1000, 9999)}"80 if user_id in users_db:81 users_db[user_id]["complaints"].append({"id": ticket_id, "issue": issue})82 return json.dumps({"ticket_id": ticket_id, "message": "Complaint registered."})83 return json.dumps({"error": "User not found"})84 85def calculate_emi(principal, rate, years):86 try:87 clean_rate = str(rate).replace('%', '').replace('percent', '').strip()88 r_value = float(clean_rate)89 p = float(principal)90 r = r_value / (12 * 100)91 n = int(years) * 1292 emi = (p * r * ((1 + r) ** n)) / (((1 + r) ** n) - 1)93 return json.dumps({"monthly_emi": f"₹{round(emi, 2)}"})94 except Exception as e:95 return json.dumps({"error": str(e)})96 97# 4. TOOL SCHEMA (The Menu)98tools = [99 {100 "type": "function", 101 "function": {102 "name": "get_balance",103 "description": "Check balance and card status.",104 "parameters": {"type": "object", "properties": {"user_id": {"type": "string"}}, "required": ["user_id"]}105 }106 },107 {108 "type": "function",109 "function": {110 "name": "get_transactions",111 "description": "Get recent transaction history/statement.",112 "parameters": {"type": "object", "properties": {"user_id": {"type": "string"}}, "required": ["user_id"]}113 }114 },115 {116 "type": "function",117 "function": {118 "name": "manage_card",119 "description": "Block or Unblock debit/credit card.",120 "parameters": {121 "type": "object", 122 "properties": {123 "user_id": {"type": "string"},124 "action": {"type": "string", "enum": ["block", "unblock"]}125 }, 126 "required": ["user_id", "action"]127 }128 }129 },130 {131 "type": "function",132 "function": {133 "name": "raise_complaint",134 "description": "Raise a complaint or issue ticket.",135 "parameters": {136 "type": "object", 137 "properties": {138 "user_id": {"type": "string"},139 "issue": {"type": "string", "description": "Description of the problem"}140 }, 141 "required": ["user_id", "issue"]142 }143 }144 },145 {146 "type": "function",147 "function": {148 "name": "calculate_emi",149 "description": "Calculate EMI.",150 "parameters": {151 "type": "object", 152 "properties": {"principal": {"type": "string"}, "rate": {"type": "string"}, "years": {"type": "string"}},153 "required": ["principal", "rate", "years"]154 }155 }156 }157]158 159# 5. THE INTELLIGENCE (System Prompt + Logic) 160 161system_instruction = """162You are NeoBank Assistant, a secure and helpful banking AI. 163Capabilities: Balance, Transactions, Card Management, EMI, Complaints.164 165RULES:1661. **Language:** Detect the user's language. If they speak Hindi, reply in Hindi. If Marathi, reply in Marathi. Default is English.1672. **Escalation:** If the user seems very angry or asks for a "human" or "agent", output the text: "[HANDOFF_TO_AGENT]".1683. **Recommendations:** If the user checks balance and has > ₹1 Lakh, suggest a "Fixed Deposit at 7.5%". If balance is low, suggest "Recurring Deposit".1694. **Currency:** Always use ₹.170"""171 172def bank_bot_response(message, history):173 messages = [{"role": "system", "content": system_instruction}]174 full_prompt = f"Current User ID is user_123. {message}"175 messages.append({"role": "user", "content": full_prompt})176 177 try:178 # Call 1: Brain179 response = client.chat.completions.create(180 model = "llama-3.3-70b-versatile",181 messages = messages, #type:ignore182 tools = tools #type:ignore183 )184 msg = response.choices[0].message185 tool_calls = msg.tool_calls186 187 if tool_calls:188 messages.append(msg) #type:ignore189 for tool_call in tool_calls:190 fname = tool_call.function.name #type:ignore191 args = json.loads(tool_call.function.arguments) #type:ignore192 193 # Routing Logic194 if fname == "get_balance": result = get_balance(args["user_id"])195 elif fname == "get_transactions": result = get_transactions(args["user_id"])196 elif fname == "manage_card": result = manage_card(args["user_id"], args["action"])197 elif fname == "raise_complaint": result = raise_complaint(args["user_id"], args["issue"])198 elif fname == "calculate_emi": result = calculate_emi(args["principal"], args["rate"], args["years"])199 else: result = "Error: Tool not found"200 201 messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": result})202 203 # Call 2: Final Answer204 final_response = client.chat.completions.create(205 model = "llama-3.3-70b-versatile",206 messages = messages #type:ignore207 )208 return final_response.choices[0].message.content209 210 else:211 return msg.content212 213 except Exception as e:214 return f"System Error: {str(e)}"215 216# 6. LAUNCH WITH VOICE SUPPORT ---217# We enable microphone input by adding 'multimodal=True' logic implicitly via Gradio's updates or simply by the ChatInterface which now supports audio in newer versions.218# To be safe, we stick to the standard interface which auto-detects audio hardware if available in browser.219 220demo = gr.ChatInterface(221 fn = bank_bot_response, 222 title = "🏦 NeoBank AI",223 multimodal = False, # Set to True if you want to force multimodal (voice + text)224)225 226demo.launch()