Datavision / backend /agents /response_enhancer.py
DataVision CI/CD Bot
release: clean production build for HuggingFace Space
09801ca
Raw
History Blame Contribute Delete
6.45 kB
"""
Autonomous Response Enhancer - 100% LLM-Driven
===============================================
NO hardcoded enhancements!
Everything is generated by LLM dynamically.
Features:
- Autonomous insight generation
- Dynamic follow-up suggestions
- Context-aware tone adjustment
- Data-specific formatting
"""
import json
import logging
from typing import Dict, List, Optional
from core.llm import chat
logger = logging.getLogger(__name__)
def extract_data_summary_from_response(response: str, currency_symbol: str = "$") -> Dict:
"""
Extract data summary autonomously using LLM.
"""
try:
prompt = f"""Analyze this data analysis response and extract key metrics.
RESPONSE: "{response[:600]}"
Return JSON with extracted data:
{{
"key_numbers": ["list of important numbers found"],
"percentages": ["any percentages mentioned"],
"entities": ["entities/names mentioned"],
"main_finding": "one sentence summary of main finding"
}}
JSON:"""
result = chat(prompt, temperature=0.1, max_tokens=150)
# Parse JSON
result = result.strip()
if '```' in result:
result = result.split('```')[1]
if result.startswith('json'):
result = result[4:]
start = result.find('{')
end = result.rfind('}') + 1
if start >= 0 and end > start:
result = result[start:end]
return json.loads(result)
except:
return {"key_numbers": [], "percentages": [], "entities": [], "main_finding": ""}
def enhance_with_insight(
response: str,
query: str,
data_context: str = ""
) -> str:
"""
Add insight fully autonomously - NO hardcoded patterns!
"""
if len(response) < 100 or "💡" in response:
return response
try:
prompt = f"""Based on this data analysis, generate ONE specific insight.
QUERY: {query}
RESPONSE: {response[:500]}
The insight should be:
- Specific to THIS data (not generic advice)
- Start with 💡
- Be 1-2 sentences max
- Provide actionable or surprising information
Generate the insight (just the insight text, starting with 💡):"""
insight = chat(prompt, temperature=0.7, max_tokens=80)
insight = insight.strip()
if insight and len(insight) > 10:
return response + f"\n\n{insight}"
except Exception as e:
logger.debug(f"Insight generation error: {e}")
return response
def enhance_with_suggestions(
response: str,
query: str,
columns: List[str] = None
) -> str:
"""
Add follow-up suggestions fully autonomously - NO hardcoding!
"""
if len(response) < 100 or "You might also" in response:
return response
try:
prompt = f"""Based on this analysis, suggest 2 natural follow-up questions.
QUERY: {query}
RESPONSE: {response[:400]}
DATA COLUMNS: {columns or "Unknown"}
Generate exactly 2 follow-up questions that would be logical next steps.
Format as:
1. [first question]
2. [second question]
Questions:"""
result = chat(prompt, temperature=0.7, max_tokens=100)
# Parse questions
lines = result.strip().split('\n')
questions = []
for line in lines:
line = line.strip()
if line and (line[0].isdigit() or line.startswith('-') or line.startswith('•')):
# Remove numbering
q = line.lstrip('0123456789.-•) ').strip()
if q and len(q) > 5:
questions.append(q)
if questions:
suggestion_text = "\n\n---\n**You might also ask:**\n"
for q in questions[:2]:
suggestion_text += f"• {q}\n"
return response + suggestion_text
except Exception as e:
logger.debug(f"Suggestion generation error: {e}")
return response
def enhance_tone(response: str, query: str) -> str:
"""
Enhance tone autonomously - NO hardcoded replacements!
"""
# Only enhance longer responses
if len(response) < 200:
return response
# Check if tone seems robotic
robotic_indicators = ['Based on the data provided', 'According to the information',
'It can be observed', 'The analysis indicates']
needs_enhancement = any(ind in response for ind in robotic_indicators)
if not needs_enhancement:
return response
try:
prompt = f"""Rewrite this response to be more natural and conversational, like ChatGPT.
Keep all the data and facts exactly the same.
Just make the tone warmer and more engaging.
ORIGINAL RESPONSE:
{response[:800]}
REWRITTEN (keep same facts, warmer tone):"""
enhanced = chat(prompt, temperature=0.5, max_tokens=800)
if enhanced and len(enhanced) > len(response) * 0.5:
return enhanced.strip()
except:
pass
return response
def enhance_full_response(
query: str,
response: str,
query_type: str = "general",
data_summary: Dict = None,
entities: List[str] = None,
add_insight: bool = True,
add_suggestions: bool = True,
enhance_tone_flag: bool = True,
currency_symbol: str = "$",
domain: str = "general",
columns: List[str] = None
) -> str:
"""
Fully autonomous response enhancement.
NO hardcoded patterns - everything LLM-driven!
"""
enhanced = response
# Enhance tone first
if enhance_tone_flag:
enhanced = enhance_tone(enhanced, query)
# Add autonomous insight
if add_insight:
enhanced = enhance_with_insight(enhanced, query)
# Add autonomous suggestions
if add_suggestions:
enhanced = enhance_with_suggestions(enhanced, query, columns)
return enhanced
def generate_autonomous_summary(
data_context: str,
columns: List[str],
num_rows: int
) -> str:
"""
Generate data summary fully autonomously.
"""
try:
prompt = f"""Generate a brief, helpful summary of this dataset.
COLUMNS: {columns}
ROWS: {num_rows}
SAMPLE DATA: {data_context[:500]}
Generate 2-3 sentences describing:
1. What kind of data this is
2. What analysis would be valuable
Summary:"""
result = chat(prompt, temperature=0.5, max_tokens=150)
return result.strip()
except:
return f"Dataset with {num_rows} rows and {len(columns)} columns."