From 1e55b9aa484bb6f67f9e34a972cf629412234dd4 Mon Sep 17 00:00:00 2001 From: Shiva Pochampally <146849983+PieLord757@users.noreply.github.com> Date: Sun, 28 Sep 2025 07:07:27 -0400 Subject: [PATCH] Removed formatting from LLM response --- .../gemini_mongo_mateo.cpython-312.pyc | Bin 16434 -> 16434 bytes .../gemini_reroute_mateo.cpython-312.pyc | Bin 26915 -> 27045 bytes llm/flask_server.py | 17 ++- llm/gemini_reroute_mateo.py | 118 ++++++++++++------ 4 files changed, 91 insertions(+), 44 deletions(-) diff --git a/llm/__pycache__/gemini_mongo_mateo.cpython-312.pyc b/llm/__pycache__/gemini_mongo_mateo.cpython-312.pyc index 30b6bab2fb7dbee1337520a31e3ef17e25290283..8bf0f1be84f88cdeae5802724d773a96cdfeb161 100644 GIT binary patch delta 21 bcmdngz__V_k?S-sFBbz4Oc&nBrQrYoLX-t9 delta 21 bcmdngz__V_k?S-sFBbz4>}T7^rQrYoLqi2f diff --git a/llm/__pycache__/gemini_reroute_mateo.cpython-312.pyc b/llm/__pycache__/gemini_reroute_mateo.cpython-312.pyc index 5f90bf31033576a47de2d7561858c7680dea3357..aebd51ab196bc99a7e758e2db485e341335747e1 100644 GIT binary patch delta 4127 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 delta 4173 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 rnyPjIrlU-;5#MDDv30sb 0: risk_factors['bicyclist'] += 1 - weather_info = f"\n\nCURRENT WEATHER CONDITIONS:\n{weather_summary}" if weather_summary else "" + # Determine safety level + total_crashes = route_safety_data.get('total_crashes_near_route', 0) + avg_score = route_safety_data.get('average_safety_score', 0) - prompt = f"""You are an expert traffic safety analyst and route planning specialist. Analyze this route's safety profile and provide recommendations. + if avg_score == 0: + safety_level = "SAFE" + elif avg_score <= 2: + safety_level = "LOW RISK" + elif avg_score <= 5: + safety_level = "MODERATE RISK" + elif avg_score <= 10: + safety_level = "HIGH RISK" + else: + safety_level = "DANGEROUS" -ROUTE INFORMATION: -- Distance: {route_info.get('distance_km', 0):.1f} km -- Estimated duration: {route_info.get('duration_min', 0):.0f} minutes -- Analysis points along route: {len(safety_points)} + weather_info = f" Current weather: {weather_summary}." if weather_summary else "" -SAFETY ANALYSIS (2020+ crash data): -- Total crashes near route: {route_safety_data.get('total_crashes_near_route', 0)} -- Average safety score: {route_safety_data.get('average_safety_score', 0):.2f} -- Maximum danger score: {route_safety_data.get('max_danger_score', 0):.2f} + prompt = f"""Analyze this route's safety and provide a concise summary with bullet points. -CRASH BREAKDOWN: -- Severity distribution: {severity_counts} -- Casualties: {casualty_summary['fatal']} fatal, {casualty_summary['major']} major injuries, {casualty_summary['minor']} minor injuries -- Risk factors: {risk_factors['speeding']} speeding-related, {risk_factors['impairment']} impairment-related -- Vulnerable users: {risk_factors['pedestrian']} pedestrian crashes, {risk_factors['bicyclist']} bicyclist crashes +ROUTE: {route_info.get('distance_km', 0):.1f}km, {route_info.get('duration_min', 0):.0f}min +CRASHES: {total_crashes} crashes nearby (2020+), safety score {avg_score:.1f} +CASUALTIES: {casualty_summary['fatal']} fatal, {casualty_summary['major']} major, {casualty_summary['minor']} minor +RISK FACTORS: {risk_factors['speeding']} speeding, {risk_factors['impairment']} impairment, {risk_factors['pedestrian']} pedestrian, {risk_factors['bicyclist']} bicyclist{weather_info} -MOST DANGEROUS SECTIONS: -{chr(10).join([f"Point {p['point_index']}: {p['crashes_count']} crashes nearby, safety score {p['safety_score']:.1f}" for p in dangerous_points[:3]])} -{weather_info} +Provide a brief summary with: +• Safety Assessment: {safety_level} +• Key Risks (2-3 bullet points max) +• Driving Tips (2-3 bullet points max) +• Weather Considerations (if applicable) -Please provide: -1. Overall route safety assessment (SAFE/MODERATE RISK/HIGH RISK/DANGEROUS) -2. Specific dangerous sections to watch out for -3. Driving recommendations for this route considering current conditions -4. Whether an alternative route should be recommended -5. Time-of-day considerations if applicable -6. Weather-specific precautions based on crash patterns - -Be specific and actionable in your recommendations.""" +Keep it concise and actionable.""" try: response = llm.invoke(prompt) - return response.content + result = response.content + + # Clean up AI response - remove all markdown formatting + if result: + import re + # Remove markdown headers (### ** ##) + result = re.sub(r'#+\s*', '', result) + # Remove bold formatting (**text**) + result = re.sub(r'\*\*([^*]+)\*\*', r'\1', result) + # Remove italic formatting (*text*) + result = re.sub(r'\*([^*]+)\*', r'\1', result) + # Convert markdown bullet points to clean bullets + result = re.sub(r'^\s*[-*+]\s*', '• ', result, flags=re.MULTILINE) + # Remove markdown code blocks + result = re.sub(r'```[^`]*```', '', result) + result = re.sub(r'`([^`]+)`', r'\1', result) + # Clean up multiple newlines but preserve structure + result = re.sub(r'\n\s*\n\s*\n', '\n\n', result) + # Clean up extra spaces within lines + result = re.sub(r'[ \t]+', ' ', result) + result = result.strip() + + return result except Exception as e: return f"Error generating safety analysis: {e}" @@ -415,24 +435,44 @@ Be specific and actionable in your recommendations.""" 'max_danger_score': safety_data.get('max_danger_score', 0) }) - weather_info = f"\nCurrent weather: {weather_summary}" if weather_summary else "" - - prompt = f"""Compare these route options for safety and provide a recommendation: + weather_info = f" Weather: {weather_summary}." if weather_summary else "" -ROUTE OPTIONS: -{chr(10).join([f"Route {r['route_num']}: {r['distance_km']:.1f}km, {r['duration_min']:.0f}min, {r['crashes_near_route']} nearby crashes, safety score {r['safety_score']:.2f}" for r in comparison_data])}{weather_info} + prompt = f"""Compare these routes briefly: + +{chr(10).join([f"Route {r['route_num']}: {r['distance_km']:.1f}km, {r['duration_min']:.0f}min, {r['crashes_near_route']} crashes, score {r['safety_score']:.1f}" for r in comparison_data])}{weather_info} Provide: -1. Which route is safest and why -2. Trade-offs between routes (safety vs. time/distance) -3. Clear recommendation with reasoning -4. Any weather-related considerations +• Recommended route and why (1-2 sentences) +• Key trade-offs (safety vs time/distance) +• Final recommendation -Keep it concise and actionable.""" +Keep it brief and clear.""" try: response = llm.invoke(prompt) - return response.content + result = response.content + + # Clean up AI response - remove all markdown formatting + if result: + import re + # Remove markdown headers (### ** ##) + result = re.sub(r'#+\s*', '', result) + # Remove bold formatting (**text**) + result = re.sub(r'\*\*([^*]+)\*\*', r'\1', result) + # Remove italic formatting (*text*) + result = re.sub(r'\*([^*]+)\*', r'\1', result) + # Convert markdown bullet points to clean bullets + result = re.sub(r'^\s*[-*+]\s*', '• ', result, flags=re.MULTILINE) + # Remove markdown code blocks + result = re.sub(r'```[^`]*```', '', result) + result = re.sub(r'`([^`]+)`', r'\1', result) + # Clean up multiple newlines but preserve structure + result = re.sub(r'\n\s*\n\s*\n', '\n\n', result) + # Clean up extra spaces within lines + result = re.sub(r'[ \t]+', ' ', result) + result = result.strip() + + return result except Exception as e: return f"Error comparing routes: {e}"