File size: 28,281 Bytes
238a495
3028ab2
 
 
 
 
 
 
dbee35a
3028ab2
84d720a
238a495
3028ab2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6dbc24
3028ab2
 
 
b381835
 
e6dbc24
3028ab2
b381835
3028ab2
 
 
 
e6dbc24
 
 
3028ab2
 
b381835
 
 
 
 
 
 
 
 
 
 
 
 
 
e6dbc24
 
 
 
b381835
 
84d720a
 
22124f7
84d720a
 
 
 
 
dbee35a
3028ab2
dbee35a
22124f7
84d720a
 
 
 
 
40fa9ed
84d720a
dbee35a
 
 
 
84d720a
 
 
 
 
 
 
 
 
b381835
3028ab2
 
b381835
 
84d720a
b381835
3028ab2
84d720a
b381835
3028ab2
 
 
dbee35a
3028ab2
dbee35a
 
 
 
3028ab2
 
 
 
 
 
 
 
 
 
 
 
84d720a
 
 
 
 
 
3028ab2
dbee35a
 
3028ab2
 
 
 
 
 
84d720a
dbee35a
 
3028ab2
 
 
 
 
 
84d720a
 
 
3028ab2
 
84d720a
dbee35a
 
3028ab2
 
 
 
 
b381835
dbee35a
 
 
 
e6dbc24
 
 
 
b381835
84d720a
b381835
 
 
 
dbee35a
3028ab2
84d720a
3028ab2
 
 
 
b381835
3028ab2
 
 
b381835
 
 
 
 
 
 
 
 
 
 
84d720a
 
 
 
 
 
b381835
 
 
84d720a
b381835
 
 
 
 
 
 
 
84d720a
b381835
 
 
 
 
 
 
 
dbee35a
b381835
 
 
 
 
 
 
3028ab2
dbee35a
 
 
 
e6dbc24
 
 
84d720a
b381835
84d720a
b381835
 
 
3028ab2
 
 
84d720a
b381835
 
3028ab2
b381835
3028ab2
 
 
 
 
 
dbee35a
 
 
 
 
 
f8f8bd3
dbee35a
f8f8bd3
cec00d2
 
dbee35a
3f48b49
 
 
 
 
f8f8bd3
dbee35a
f8f8bd3
cec00d2
 
 
dbee35a
cec00d2
 
dbee35a
 
cec00d2
 
b381835
dbee35a
 
 
f8f8bd3
cec00d2
 
 
dbee35a
f8f8bd3
dbee35a
f8f8bd3
cec00d2
 
dbee35a
f8f8bd3
cec00d2
dbee35a
 
f8f8bd3
cec00d2
 
 
dbee35a
 
 
f8f8bd3
 
 
cec00d2
 
 
dbee35a
cec00d2
dbee35a
 
f8f8bd3
dbee35a
cec00d2
dbee35a
 
 
f8f8bd3
dbee35a
 
cec00d2
 
 
 
dbee35a
 
cec00d2
dbee35a
 
f8f8bd3
cec00d2
dbee35a
3f48b49
dbee35a
f8f8bd3
 
cec00d2
 
84d720a
 
dbee35a
 
cec00d2
84d720a
3f48b49
 
 
 
 
dbee35a
f8f8bd3
dbee35a
cec00d2
dbee35a
cec00d2
 
dbee35a
cec00d2
 
dbee35a
 
f8f8bd3
dbee35a
 
f8f8bd3
dbee35a
 
cec00d2
f8f8bd3
dbee35a
f8f8bd3
dbee35a
 
 
f8f8bd3
 
 
cec00d2
 
 
 
dbee35a
 
f8f8bd3
cec00d2
dbee35a
f8f8bd3
dbee35a
f8f8bd3
dbee35a
 
cec00d2
 
 
 
dbee35a
 
 
f8f8bd3
cec00d2
dbee35a
 
 
 
 
f8f8bd3
cec00d2
 
dbee35a
f8f8bd3
cec00d2
dbee35a
 
 
 
f8f8bd3
cec00d2
 
 
dbee35a
 
 
cec00d2
dbee35a
 
f8f8bd3
dbee35a
 
f8f8bd3
cec00d2
dbee35a
 
 
 
f8f8bd3
cec00d2
 
 
 
 
 
dbee35a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3028ab2
dbee35a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84d720a
dbee35a
 
 
 
 
3028ab2
 
 
 
 
 
dbee35a
3028ab2
 
 
 
 
dbee35a
3028ab2
 
dbee35a
 
 
 
 
 
f8f8bd3
dbee35a
 
 
 
 
 
 
 
 
3028ab2
238a495
 
3028ab2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
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 .env environment variables
load_dotenv()
api_key = os.getenv("GROQ_API_KEY")
client = Groq(api_key=api_key)
MODEL_NAME = "llama-3.3-70b-versatile"

# In-memory cache for search results
search_cache = defaultdict(str)
cache_timeout = 3600  # 1 hour

# In-memory Q&A store for community simulation
community_qa = []

# Diagnostics knowledge base (simplified)
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
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."
]

# Tool: DuckDuckGo web search with retry and structured output
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 for garage search
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"
]

# Detect language and extract car model from input
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

# ReAct agent response with thought process
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

        # Detect language and car model from message
        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()

        # Initialize messages with system prompt
        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}]
        
        # Convert Gradio chat history to OpenAI-style format
        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})

        # Check diagnostics database
        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

        # Check for community Q&A keywords
        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

        # Check for trigger keywords to directly perform search
        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

        # General car conversation using LLM with ReAct debugging
        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:
                # Extract JSON from raw response, handling extra text
                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

# Gradio interface with enhanced, customer-centric UI
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:
    # Header with car-themed branding
    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>
            """
        )

    # Navigation tabs for quick access
    with gr.Row():
        gr.Markdown(
            """
            <div class='nav-tabs'>
                <button class='active'>🚘 Profile</button>
                <button>🔧 Diagnostics</button>
                <button>🗣️ Community</button>
            </div>
            """
        )

    # Vehicle profile inputs
    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": ""})
    
    # Update vehicle profile
    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
    )
    
    # Chat interface with enhanced styling
    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"
    )

    # Footer
    gr.Markdown(
        """
        <div class='footer'>
            Powered by CarMaa © 2025 | Your Trusted Car Care Companion
        </div>
        """
    )

if __name__ == "__main__":
    demo.launch(share=True)