|
import gradio as gr |
|
from groq import Groq |
|
from dotenv import load_dotenv |
|
import os |
|
import traceback |
|
import json |
|
import time |
|
from collections import defaultdict |
|
from duckduckgo_search import DDGS |
|
import requests |
|
import re |
|
|
|
|
|
load_dotenv() |
|
api_key = os.getenv("GROQ_API_KEY") |
|
client = Groq(api_key=api_key) |
|
MODEL_NAME = "llama-3.3-70b-versatile" |
|
|
|
|
|
search_cache = defaultdict(str) |
|
cache_timeout = 3600 |
|
|
|
|
|
community_qa = [] |
|
|
|
|
|
diagnostics_db = { |
|
"Maruti Alto": { |
|
"check engine light": { |
|
"causes": ["Faulty oxygen sensor", "Loose fuel cap", "Spark plug issues"], |
|
"solutions": ["Run OBD-II scan (₹500-₹1500)", "Tighten/replace fuel cap (₹100-₹500)", "Replace spark plugs (₹1000-₹2000)"], |
|
"severity": "Moderate" |
|
}, |
|
"poor fuel efficiency": { |
|
"causes": ["Clogged air filter", "Tire underinflation", "Fuel injector issues"], |
|
"solutions": ["Replace air filter (₹300-₹800)", "Check tire pressure (free)", "Clean/replace injectors (₹2000-₹5000)"], |
|
"severity": "Low" |
|
} |
|
}, |
|
"Hyundai i20": { |
|
"ac not cooling": { |
|
"causes": ["Low refrigerant", "Faulty compressor", "Clogged condenser"], |
|
"solutions": ["Refill refrigerant (₹1500-₹3000)", "Repair/replace compressor (₹5000-₹15000)", "Clean condenser (₹1000-₹2000)"], |
|
"severity": "High" |
|
} |
|
} |
|
} |
|
|
|
|
|
maintenance_tips = [ |
|
"Check tire pressure monthly to improve fuel efficiency.", |
|
"Change engine oil every 10,000 km or 6 months for Indian road conditions.", |
|
"Inspect brakes regularly, especially during monsoon seasons.", |
|
"Keep your car clean to prevent rust in humid climates." |
|
] |
|
|
|
|
|
def web_search_duckduckgo(query: str, max_results: int = 5, max_retries: int = 2): |
|
cache_key = query.lower() |
|
if cache_key in search_cache: |
|
cached_time, cached_results = search_cache[cache_key] |
|
if time.time() - cached_time < cache_timeout: |
|
print(f"Using cached results for: {query}") |
|
return cached_results |
|
|
|
results = [] |
|
for attempt in range(max_retries): |
|
try: |
|
print(f"Attempting DuckDuckGo search for: {query} (Attempt {attempt + 1})") |
|
with DDGS() as ddgs: |
|
for r in ddgs.text(query, region="in-en", safesearch="Moderate", max_results=max_results): |
|
results.append({"title": r['title'], "url": r['href']}) |
|
if not results: |
|
raise ValueError("No results found") |
|
formatted_results = "\n".join(f"- [{r['title']}]({r['url']})" for r in results) |
|
search_cache[cache_key] = (time.time(), formatted_results) |
|
print(f"Search results for {query}: {formatted_results}") |
|
return formatted_results |
|
except Exception as e: |
|
print(f"Search attempt {attempt + 1} failed: {str(e)}") |
|
if attempt + 1 == max_retries: |
|
error_message = f"⚠️ Web search failed after {max_retries} attempts: {str(e)}" |
|
search_cache[cache_key] = (time.time(), error_message) |
|
return error_message |
|
time.sleep(1) |
|
|
|
|
|
trigger_keywords = [ |
|
"garage near", "car service near", "repair shop in", "mechanic in", "car workshop near", |
|
"tyre change near", "puncture repair near", "engine repair near", "car wash near", |
|
"car ac repair", "suspension work", "car battery replacement", "headlight change", |
|
"oil change near", "nearby service center", "wheel alignment near", "wheel balancing", |
|
"car painting service", "denting and painting", "car insurance repair", "maruti workshop", |
|
"hyundai service", "honda repair center", "toyota garage", "tata motors service", |
|
"mahindra car repair", "nexa service center", "kia workshop", "ev charging near", |
|
"ev repair", "gearbox repair", "clutch repair", "brake pad replacement", |
|
"windshield repair", "car glass replacement", "coolant top up", "engine tuning", |
|
"car noise issue", "check engine light", "dashboard warning light", "local garage", |
|
"trusted mechanic", "authorized service center", "car towing service near me", |
|
"car not starting", "flat battery", "jump start service", "roadside assistance", |
|
"ac not cooling", "car breakdown", "pickup and drop car service", "service centers for car repair", |
|
"interior car cleaning", "paint protection", "ceramic coating", "glass coating", "surface coating", |
|
"full car detailing", "exterior car cleaning", "car dry cleaning", "car body polish", "full car wash", |
|
"deep cleaning", "car decor" |
|
] |
|
|
|
|
|
def detect_language_and_model(message): |
|
hindi_keywords = ["namaste", "kaise", "hai", "mere", "pas", "hai"] |
|
if any(keyword in message.lower() for keyword in hindi_keywords): |
|
return "hindi", re.search(r'(maruti|alto|tata|nexon|mahindra|scorpio|hyundai|creta|honda|city)\s*(\d{4})?', message.lower()) |
|
return "english", None |
|
|
|
|
|
def respond(message, history, vehicle_profile): |
|
try: |
|
system_message = ( |
|
"You are CarMaa, a totally Indian car Doctor and mechanic,you are friendly, and highly knowledgeable AI Car Doctor specializing in Indian cars. Your mission is to assist users with detailed, practical advice on car care, maintenance, and troubleshooting, tailored for Indian driving conditions. " |
|
"You have deep expertise in Indian car brands like Maruti Suzuki, Tata Motors, Mahindra, Hyundai India, and Honda Cars India, including popular models such as Maruti Alto, Tata Nexon, Mahindra Scorpio, Hyundai Creta, and Honda City. " |
|
"You understand the unique challenges of Indian roads—monsoon flooding, potholes, extreme heat, and heavy traffic—and can provide advice on common issues like engine overheating, suspension wear, AC failures, and fuel efficiency problems. " |
|
"You are also well-versed in Indian market trends (e.g., rise of EVs like Tata Nexon EV, government policies on BS6 norms), you can also differentiate between petrol, diesel, hybrids and EV and give answers to queries according to them, car features (e.g., CNG variants, AMT transmissions), and driving experiences (e.g., long drives on NH44, city driving in Delhi). " |
|
"As an AI doctor, you can diagnose car problems based on user descriptions (e.g., 'weird noise from engine', 'check engine light on'), suggest solutions with estimated costs in INR (e.g., 'replace alternator, ~₹5000'), and recommend maintenance tips for Indian climates (e.g., 'check coolant levels before summer'). " |
|
"For location-specific queries (e.g., garages, repair shops, authorized service centers in Mumbai), you MUST use the 'search' action to fetch real-time data using the web search tool. For general car conversations, engage users naturally with a casual, friendly tone, sharing insights about Indian cars and driving culture. " |
|
"Always respond with a valid JSON object containing 'thought', 'observation', 'action', and 'response' or 'search_query'. Do NOT include any text outside the JSON object. Respond in the user's preferred language you can do English and Hindi(e.g., Hindi if they use Hindi phrases like 'Namaste Ji')." |
|
) |
|
max_tokens = 1024 |
|
temperature = 0.7 |
|
top_p = 0.95 |
|
|
|
|
|
lang, model_match = detect_language_and_model(message) |
|
if model_match: |
|
make_model = model_match.group(0).replace(" ", "") |
|
if "2000" in make_model and "alto" in make_model.lower(): |
|
vehicle_profile["make_model"] = "Maruti Alto" |
|
elif make_model: |
|
vehicle_profile["make_model"] = make_model.title() |
|
|
|
|
|
react_prompt = ( |
|
f"{system_message}\n\n" |
|
"For each user query, follow these steps:\n" |
|
"1. **Thought**: Assess if the query requires a web search (e.g., for garages or real-time data) or is a general car-related conversation.\n" |
|
"2. **Observation**: Note the user's input, language preference, and vehicle profile context.\n" |
|
"3. **Action**: Choose 'search' for location-specific queries, 'respond' for general conversation, or other actions as needed.\n" |
|
f"User vehicle profile: {json.dumps(vehicle_profile)}\n" |
|
f"Respond in {lang} if possible, matching the user's language preference." |
|
"Use the LLM to generate a conversational response for general car topics, but prioritize web search for location-specific queries." |
|
) |
|
messages = [{"role": "system", "content": react_prompt}] |
|
|
|
|
|
for msg in history: |
|
if msg["role"] == "user": |
|
messages.append({"role": "user", "content": msg["content"]}) |
|
elif msg["role"] == "assistant": |
|
messages.append({"role": "assistant", "content": msg["content"]}) |
|
messages.append({"role": "user", "content": message}) |
|
|
|
|
|
if vehicle_profile.get("make_model") and any(kw in message.lower() for kw in diagnostics_db.get(vehicle_profile["make_model"], {})): |
|
for issue, details in diagnostics_db[vehicle_profile["make_model"]].items(): |
|
if issue in message.lower(): |
|
response = ( |
|
f"**Diagnosed Issue**: {issue}\n" |
|
f"- **Possible Causes**: {', '.join(details['causes'])}\n" |
|
f"- **Solutions**: {', '.join(details['solutions'])}\n" |
|
f"- **Severity**: {details['severity']}\n" |
|
f"Would you like to search for garages to address this issue or learn more?" |
|
) if lang == "english" else ( |
|
f"**Problem**: {issue}\n" |
|
f"- **Karan**: {', '.join(details['causes'])}\n" |
|
f"- **Samadhan**: {', '.join(details['solutions'])}\n" |
|
f"- **Sankat**: {details['severity']}\n" |
|
f"Kya aap iska garage dhundhna chahte hain ya aur janna chahte hain?" |
|
) |
|
for i in range(0, len(response), 10): |
|
yield response[:i + 10] |
|
return |
|
|
|
|
|
if any(kw in message.lower() for kw in ["community", "forum", "discussion", "share advice", "ask community"]): |
|
if "post" in message.lower() or "share" in message.lower(): |
|
community_qa.append({"question": message, "answers": []}) |
|
response = "Your question has been posted to the community! Check back for answers." if lang == "english" else "Aapka sawal community mein post kar diya gaya hai! Jawab ke liye wapas dekhein." |
|
for i in range(0, len(response), 10): |
|
yield response[:i + 10] |
|
return |
|
elif "view" in message.lower() or "see" in message.lower(): |
|
if community_qa: |
|
response = "Community Q&A:\n" + "\n".join( |
|
f"Q: {qa['question']}\nA: {', '.join(qa['answers']) or 'No answers yet'}" |
|
for qa in community_qa |
|
) if lang == "english" else "Community Q&A:\n" + "\n".join( |
|
f"Sawal: {qa['question']}\nJawab: {', '.join(qa['answers']) or 'Abhi tak koi jawab nahi'}" |
|
for qa in community_qa |
|
) |
|
else: |
|
response = "No community questions yet. Post one with 'share' or 'post'!" if lang == "english" else "Abhi tak koi community sawal nahi. 'Share' ya 'post' se ek sawal daalein!" |
|
for i in range(0, len(response), 10): |
|
yield response[:i + 10] |
|
return |
|
|
|
|
|
if any(keyword in message.lower() for keyword in trigger_keywords): |
|
print(f"Trigger keyword detected in query: {message}") |
|
search_query = message.replace("reapir", "repair") |
|
if "car" not in search_query.lower(): |
|
search_query = f"car {search_query}" |
|
if vehicle_profile.get("city"): |
|
search_query = f"{search_query} {vehicle_profile['city']}" |
|
uttarakhand_cities = ["dehradun", "haridwar", "roorkee", "haldwani", "nainital", "rudrapur"] |
|
carmaa_recommendation = "" |
|
if any(city in vehicle_profile['city'].lower() for city in uttarakhand_cities): |
|
carmaa_recommendation = "- [CarMaa Car Care - Recommended](https://carmaacarcare.com/contactus/)\n" |
|
else: |
|
response = "I'd be happy to help you find repair workshops near you. However, I need to know your location. Could you please tell me your city or update your vehicle profile?" if lang == "english" else "Main aapko repair workshop dhundhne mein madad karunga, lekin mujhe aapka shahar pata hona chahiye. Kya aap apna shahar batayenge ya profile update karenge?" |
|
for i in range(0, len(response), 10): |
|
yield response[:i + 10] |
|
return |
|
print(f"Performing web search for: {search_query}") |
|
search_results = web_search_duckduckgo(search_query) |
|
print(f"Search Results:\n{search_results}") |
|
final_response = f"🔍 Here are some car repair service centers I found:\n\n{carmaa_recommendation}{search_results}\n\n**Tip**: {maintenance_tips[hash(message) % len(maintenance_tips)]}" if lang == "english" else f"🔍 Ye kuch car repair service centers hain jo mujhe mile:\n\n{carmaa_recommendation}{search_results}\n\n**Tip**: {maintenance_tips[hash(message) % len(maintenance_tips)]}" |
|
for i in range(0, len(final_response), 10): |
|
yield final_response[:i + 10] |
|
return |
|
|
|
|
|
max_iterations = 3 |
|
for iteration in range(max_iterations): |
|
print(f"\n--- ReAct Iteration {iteration + 1} ---") |
|
completion = client.chat.completions.create( |
|
model=MODEL_NAME, |
|
messages=messages, |
|
temperature=temperature, |
|
max_completion_tokens=max_tokens, |
|
top_p=top_p, |
|
stream=False, |
|
) |
|
raw_response = completion.choices[0].message.content |
|
print(f"Raw LLM Response: {raw_response}") |
|
try: |
|
|
|
json_match = re.search(r'\{.*\}', raw_response, re.DOTALL) |
|
if json_match: |
|
react_step = json.loads(json_match.group(0)) |
|
else: |
|
raise json.JSONDecodeError("No JSON object found", raw_response, 0) |
|
thought = react_step.get("thought", "") |
|
observation = react_step.get("observation", "") |
|
action = react_step.get("action", "") |
|
response = react_step.get("response", "Let's chat about cars! What do you think about the latest models or features?") if lang == "english" else react_step.get("response", "Gaadi ke baare mein baat karein! Aapko naye models ya features ke baare mein kya lagta hai?") |
|
print(f"Thought: {thought}") |
|
print(f"Observation: {observation}") |
|
print(f"Action: {action}") |
|
except json.JSONDecodeError: |
|
react_step = { |
|
"thought": "User input seems general, using LLM for conversation.", |
|
"observation": f"Input: {message}", |
|
"action": "respond", |
|
"response": "Let's chat about cars! What do you think about the latest models or features?" if lang == "english" else "Gaadi ke baare mein baat karein! Aapko naye models ya features ke baare mein kya lagta hai?" |
|
} |
|
thought = react_step["thought"] |
|
observation = react_step["observation"] |
|
action = react_step["action"] |
|
response = react_step["response"] |
|
print(f"Thought: {thought}") |
|
print(f"Observation: {observation}") |
|
print(f"Action: {action}") |
|
|
|
if action == "respond": |
|
current_response = f"{response}\n\n**Tip**: {maintenance_tips[hash(message) % len(maintenance_tips)]}" |
|
print(f"Final Response: {current_response}") |
|
for i in range(0, len(current_response), 10): |
|
yield current_response[:i + 10] |
|
break |
|
elif action == "search": |
|
search_query = react_step.get("search_query", message) |
|
if "car" not in search_query.lower(): |
|
search_query = f"car {search_query}" |
|
if vehicle_profile.get("city"): |
|
search_query = f"{search_query} {vehicle_profile['city']}" |
|
uttarakhand_cities = ["dehradun", "haridwar", "roorkee", "haldwani", "nainital", "rudrapur"] |
|
carmaa_recommendation = "" |
|
if any(city in vehicle_profile['city'].lower() for city in uttarakhand_cities): |
|
carmaa_recommendation = "- [CarMaa Car Care - Recommended](https://carmaacarcare.com/)\n" |
|
else: |
|
response = "I'd be happy to help you find repair workshops near you. However, I need to know your location. Could you please tell me your city or update your vehicle profile?" if lang == "english" else "Main aapko repair workshop dhundhne mein madad karunga, lekin mujhe aapka shahar pata hona chahiye. Kya aap apna shahar batayenge ya profile update karenge?" |
|
for i in range(0, len(response), 10): |
|
yield response[:i + 10] |
|
return |
|
print(f"Performing web search for: {search_query}") |
|
search_results = web_search_duckduckgo(search_query) |
|
print(f"Search Results:\n{search_results}") |
|
final_response = f"🔍 Here are some car repair service centers I found:\n\n{carmaa_recommendation}{search_results}\n\n**Tip**: {maintenance_tips[hash(message) % len(maintenance_tips)]}" if lang == "english" else f"🔍 Ye kuch car repair service centers hain jo mujhe mile:\n\n{carmaa_recommendation}{search_results}\n\n**Tip**: {maintenance_tips[hash(message) % len(maintenance_tips)]}" |
|
for i in range(0, len(final_response), 10): |
|
yield final_response[:i + 10] |
|
break |
|
messages.append({"role": "assistant", "content": json.dumps(react_step)}) |
|
|
|
except Exception as e: |
|
error_msg = f"❌ Error: {str(e)}\n{traceback.format_exc()}" |
|
print(error_msg) |
|
yield error_msg |
|
|
|
|
|
with gr.Blocks( |
|
title="CarMaa - India's AI Car Doctor", |
|
css=""" |
|
/* Overall layout and background */ |
|
.gradio-container { |
|
background: linear-gradient(135deg, #e6f0fa, #b3d4fc); |
|
font-family: 'Arial', sans-serif; |
|
color: #003087; |
|
padding: 20px; |
|
min-height: 100vh; |
|
} |
|
/* Ensure the parent container allows growth */ |
|
.gradio-container > div { |
|
height: auto !important; |
|
min-height: 100vh !important; |
|
} |
|
/* Header styling with clean design */ |
|
.header { |
|
background: #ffffff; |
|
padding: 25px; |
|
border-radius: 12px; |
|
border-bottom: 4px solid #007bff; |
|
text-align: center; |
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); |
|
margin-bottom: 20px; |
|
} |
|
.header h1 { |
|
font-size: 2.8em; |
|
font-weight: 700; |
|
color: #003087; |
|
margin: 0; |
|
} |
|
.header p { |
|
color: #003087; |
|
font-size: 1.2em; |
|
margin-top: 8px; |
|
font-weight: 500; |
|
} |
|
/* Vehicle profile inputs with clean styling */ |
|
.vehicle-profile { |
|
background: #ffffff; |
|
padding: 25px; |
|
border-radius: 10px; |
|
margin: 20px 0; |
|
border: 1px solid #b3d4fc; |
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); |
|
} |
|
.vehicle-profile label { |
|
color: #007bff; |
|
font-weight: 600; |
|
font-size: 1.1em; |
|
margin-bottom: 8px; |
|
display: block; |
|
} |
|
.vehicle-profile input { |
|
background: #f9f9f9; |
|
color: #003087; |
|
border: 1px solid #b3d4fc; |
|
border-radius: 6px; |
|
padding: 12px; |
|
font-size: 1em; |
|
width: 100%; |
|
transition: border-color 0.3s, box-shadow 0.3s; |
|
} |
|
.vehicle-profile input:focus { |
|
border-color: #007bff; |
|
outline: none; |
|
box-shadow: 0 0 6px rgba(0, 123, 255, 0.3); |
|
} |
|
/* Save button with hover animation */ |
|
.save-btn { |
|
background: #007bff !important; |
|
color: #ffffff !important; |
|
border: none !important; |
|
padding: 14px !important; |
|
border-radius: 6px !important; |
|
font-weight: 600 !important; |
|
font-size: 1.1em !important; |
|
transition: transform 0.2s, background 0.3s !important; |
|
width: 100% !important; |
|
margin-top: 15px !important; |
|
} |
|
.save-btn:hover { |
|
background: #0056b3 !important; |
|
transform: scale(1.03); |
|
} |
|
/* Chat container with increased height */ |
|
.chatbot-container { |
|
background: #ffffff; |
|
border: 2px solid #b3d4fc; |
|
border-radius: 10px; |
|
padding: 20px; |
|
max-height: 1000px !important; |
|
min-height: 400px !important; |
|
overflow-y: auto; |
|
margin-bottom: 20px; |
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); |
|
height: auto !important; |
|
} |
|
/* Ensure the chat interface itself can grow */ |
|
.chatbot-container .gr-chatbot { |
|
max-height: 1000px !important; |
|
height: auto !important; |
|
} |
|
/* Chat messages with clean styling */ |
|
.chatbot-container .message-user div, .chatbot-container .message-assistant div { |
|
padding: 12px !important; |
|
border-radius: 8px !important; |
|
margin-bottom: 12px !important; |
|
max-width: 85% !important; |
|
word-wrap: break-word !important; |
|
font-size: 1em !important; |
|
line-height: 1.5 !important; |
|
} |
|
.chatbot-container .message-user div { |
|
background: #007bff !important; |
|
color: #ffffff !important; |
|
margin-left: auto !important; |
|
border: 1px solid #0056b3 !important; |
|
} |
|
.chatbot-container .message-assistant div { |
|
background: #f0f7ff !important; |
|
color: #003087 !important; |
|
margin-right: auto !important; |
|
border: 1px solid #b3d4fc !important; |
|
} |
|
/* Chat input area */ |
|
.chatbot-container textarea { |
|
background: #f9f9f9 !important; |
|
color: #003087 !important; |
|
border: 1px solid #b3d4fc !important; |
|
border-radius: 6px !important; |
|
padding: 12px !important; |
|
font-size: 1em !important; |
|
transition: border-color 0.3s, box-shadow 0.3s !important; |
|
} |
|
.chatbot-container textarea:focus { |
|
border-color: #007bff !important; |
|
box-shadow: 0 0 6px rgba(0, 123, 255, 0.3) !important; |
|
} |
|
/* Send button with clean design */ |
|
.chatbot-container button { |
|
background: #007bff !important; |
|
color: #ffffff !important; |
|
border: none !important; |
|
border-radius: 6px !important; |
|
padding: 12px 24px !important; |
|
font-weight: 600 !important; |
|
font-size: 1em !important; |
|
transition: transform 0.2s, background 0.3s !important; |
|
} |
|
.chatbot-container button:hover { |
|
background: #0056b3 !important; |
|
transform: scale(1.03); |
|
} |
|
/* Navigation tabs for quick access */ |
|
.nav-tabs { |
|
display: flex; |
|
justify-content: space-around; |
|
background: #ffffff; |
|
padding: 12px 0; |
|
border-radius: 10px; |
|
margin-bottom: 20px; |
|
border: 1px solid #b3d4fc; |
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); |
|
} |
|
.nav-tabs button { |
|
background: none; |
|
border: none; |
|
color: #003087; |
|
font-weight: 600; |
|
font-size: 1.1em; |
|
padding: 12px; |
|
transition: color 0.3s; |
|
display: flex; |
|
align-items: center; |
|
gap: 6px; |
|
} |
|
.nav-tabs button:hover { |
|
color: #007bff; |
|
} |
|
.nav-tabs button.active { |
|
color: #007bff; |
|
border-bottom: 3px solid #007bff; |
|
} |
|
/* Footer with subtle branding */ |
|
.footer { |
|
text-align: center; |
|
color: #003087; |
|
font-size: 1em; |
|
font-weight: 500; |
|
margin-top: 25px; |
|
padding: 10px; |
|
background: rgba(255, 255, 255, 0.9); |
|
border-radius: 8px; |
|
} |
|
""" |
|
) as demo: |
|
|
|
with gr.Row(): |
|
gr.Markdown( |
|
""" |
|
<div class='header'> |
|
<h1>🚗 CarMaa - India's AI Car Doctor</h1> |
|
<p>Diagnose issues, find garages, and connect with the car community!</p> |
|
</div> |
|
""" |
|
) |
|
|
|
|
|
with gr.Row(): |
|
gr.Markdown( |
|
""" |
|
<div class='nav-tabs'> |
|
<button class='active'>🚘 Profile</button> |
|
<button>🔧 Diagnostics</button> |
|
<button>🗣️ Community</button> |
|
</div> |
|
""" |
|
) |
|
|
|
|
|
with gr.Row(variant="panel", elem_classes="vehicle-profile"): |
|
make_model = gr.Textbox( |
|
label="Vehicle Make and Model", |
|
placeholder="e.g., Maruti Alto" |
|
) |
|
year = gr.Textbox( |
|
label="Year", |
|
placeholder="e.g., 2000" |
|
) |
|
city = gr.Textbox( |
|
label="City", |
|
placeholder="e.g., Delhi" |
|
) |
|
vehicle_profile = gr.State(value={"make_model": "", "year": "", "city": ""}) |
|
|
|
|
|
def update_vehicle_profile(make_model, year, city): |
|
return {"make_model": make_model, "year": year, "city": city} |
|
|
|
gr.Button("Save Vehicle Profile", elem_classes="save-btn").click( |
|
fn=update_vehicle_profile, |
|
inputs=[make_model, year, city], |
|
outputs=vehicle_profile |
|
) |
|
|
|
|
|
chatbot = gr.ChatInterface( |
|
fn=respond, |
|
additional_inputs=[vehicle_profile], |
|
title="", |
|
description="Ask about car diagnostics, garage locations, or community advice.", |
|
theme="soft", |
|
textbox=gr.Textbox(placeholder="Ask about your car... 🚘"), |
|
submit_btn="Send 🚀", |
|
type="messages" |
|
) |
|
|
|
|
|
gr.Markdown( |
|
""" |
|
<div class='footer'> |
|
Powered by CarMaa © 2025 | Your Trusted Car Care Companion |
|
</div> |
|
""" |
|
) |
|
|
|
if __name__ == "__main__": |
|
demo.launch(share=True) |