Pulastya B commited on
Commit
dd1f6f0
Β·
1 Parent(s): 9585bf4

Fix session file persistence and modal title issues

Browse files

CRITICAL FIXES:

1. Session File Persistence (Backend):
- Moved session resolution BEFORE schema extraction
- Follow-up requests now properly retrieve dataset from session
- Fixes 'No such file or directory' error on follow-up requests
- Schema extraction now happens AFTER file_path is resolved

2. Modal Title Display (Frontend):
- Added reportModalTitle state variable
- Modal now shows actual plot/report name instead of hardcoded 'Data Profiling Report'
- Title updates when opening any visualization or report
- Titles: 'Correlation Heatmap', 'EDA Report', etc.

These fixes enable:
- Seamless follow-up requests without re-uploading files
- Proper identification of what visualization is being viewed
- Better UX with accurate modal titles

FRRONTEEEND/components/ChatInterface.tsx CHANGED
@@ -48,6 +48,7 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
48
  const [currentStep, setCurrentStep] = useState<string>('');
49
  const [uploadedFile, setUploadedFile] = useState<File | null>(null);
50
  const [reportModalUrl, setReportModalUrl] = useState<string | null>(null);
 
51
  const [showAssets, setShowAssets] = useState(false);
52
  const fileInputRef = useRef<HTMLInputElement>(null);
53
  const scrollRef = useRef<HTMLDivElement>(null);
@@ -702,7 +703,7 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
702
  return (
703
  <button
704
  key={idx}
705
- onClick={() => setReportModalUrl(`${window.location.origin}${normalizedPath}`)}
706
  className="flex items-center gap-2 px-4 py-2 rounded-lg bg-indigo-500/20 hover:bg-indigo-500/30 border border-indigo-500/30 text-indigo-200 text-xs font-medium transition-all group"
707
  >
708
  <Sparkles className="w-3.5 h-3.5 group-hover:scale-110 transition-transform" />
@@ -722,7 +723,7 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
722
  {msg.plots.map((plot, idx) => (
723
  <button
724
  key={idx}
725
- onClick={() => setReportModalUrl(`${window.location.origin}${plot.url}`)}
726
  className="flex items-center gap-2 px-4 py-2 rounded-lg bg-emerald-500/20 hover:bg-emerald-500/30 border border-emerald-500/30 text-emerald-200 text-xs font-medium transition-all group"
727
  >
728
  <svg className="w-3.5 h-3.5 group-hover:scale-110 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -896,7 +897,7 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
896
  return (
897
  <button
898
  key={idx}
899
- onClick={() => setReportModalUrl(plotUrl || plot.url)}
900
  className="w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-emerald-500/10 hover:border-emerald-500/30 transition-all text-left group"
901
  >
902
  <div className="flex items-center justify-between">
@@ -1007,7 +1008,7 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
1007
  {allReports.map((report, idx) => (
1008
  <button
1009
  key={idx}
1010
- onClick={() => setReportModalUrl(report.path)}
1011
  className="w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-purple-500/10 hover:border-purple-500/30 transition-all text-left group"
1012
  >
1013
  <div className="flex items-center justify-between">
@@ -1044,7 +1045,7 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
1044
  animate={{ opacity: 1 }}
1045
  exit={{ opacity: 0 }}
1046
  className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4"
1047
- onClick={() => setReportModalUrl(null)}
1048
  >
1049
  <motion.div
1050
  initial={{ scale: 0.95, opacity: 0 }}
@@ -1054,9 +1055,9 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
1054
  onClick={(e) => e.stopPropagation()}
1055
  >
1056
  <div className="flex items-center justify-between p-4 border-b border-white/5">
1057
- <h3 className="text-lg font-semibold text-white">Data Profiling Report</h3>
1058
  <button
1059
- onClick={() => setReportModalUrl(null)}
1060
  className="p-2 rounded-lg hover:bg-white/5 transition-colors"
1061
  >
1062
  <X className="w-5 h-5" />
 
48
  const [currentStep, setCurrentStep] = useState<string>('');
49
  const [uploadedFile, setUploadedFile] = useState<File | null>(null);
50
  const [reportModalUrl, setReportModalUrl] = useState<string | null>(null);
51
+ const [reportModalTitle, setReportModalTitle] = useState<string>('Visualization');
52
  const [showAssets, setShowAssets] = useState(false);
53
  const fileInputRef = useRef<HTMLInputElement>(null);
54
  const scrollRef = useRef<HTMLDivElement>(null);
 
703
  return (
704
  <button
705
  key={idx}
706
+ onClick={() => { setReportModalUrl(`${window.location.origin}${normalizedPath}`); setReportModalTitle(report.name || 'Report'); }}
707
  className="flex items-center gap-2 px-4 py-2 rounded-lg bg-indigo-500/20 hover:bg-indigo-500/30 border border-indigo-500/30 text-indigo-200 text-xs font-medium transition-all group"
708
  >
709
  <Sparkles className="w-3.5 h-3.5 group-hover:scale-110 transition-transform" />
 
723
  {msg.plots.map((plot, idx) => (
724
  <button
725
  key={idx}
726
+ onClick={() => { setReportModalUrl(`${window.location.origin}${plot.url}`); setReportModalTitle(plot.title || 'Visualization'); }}
727
  className="flex items-center gap-2 px-4 py-2 rounded-lg bg-emerald-500/20 hover:bg-emerald-500/30 border border-emerald-500/30 text-emerald-200 text-xs font-medium transition-all group"
728
  >
729
  <svg className="w-3.5 h-3.5 group-hover:scale-110 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor">
 
897
  return (
898
  <button
899
  key={idx}
900
+ onClick={() => { setReportModalUrl(plotUrl || plot.url); setReportModalTitle(plot.title || 'Visualization'); }}
901
  className="w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-emerald-500/10 hover:border-emerald-500/30 transition-all text-left group"
902
  >
903
  <div className="flex items-center justify-between">
 
1008
  {allReports.map((report, idx) => (
1009
  <button
1010
  key={idx}
1011
+ onClick={() => { setReportModalUrl(report.path); setReportModalTitle(report.name || 'Report'); }}
1012
  className="w-full p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-purple-500/10 hover:border-purple-500/30 transition-all text-left group"
1013
  >
1014
  <div className="flex items-center justify-between">
 
1045
  animate={{ opacity: 1 }}
1046
  exit={{ opacity: 0 }}
1047
  className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4"
1048
+ onClick={() => { setReportModalUrl(null); setReportModalTitle('Visualization'); }}
1049
  >
1050
  <motion.div
1051
  initial={{ scale: 0.95, opacity: 0 }}
 
1055
  onClick={(e) => e.stopPropagation()}
1056
  >
1057
  <div className="flex items-center justify-between p-4 border-b border-white/5">
1058
+ <h3 className="text-lg font-semibold text-white">{reportModalTitle}</h3>
1059
  <button
1060
+ onClick={() => { setReportModalUrl(null); setReportModalTitle('Visualization'); }}
1061
  className="p-2 rounded-lg hover:bg-white/5 transition-colors"
1062
  >
1063
  <X className="w-5 h-5" />
src/orchestrator.py CHANGED
@@ -2094,7 +2094,33 @@ You are a DOER. Complete workflows based on user intent."""
2094
  """
2095
  start_time = time.time()
2096
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2097
  # πŸš€ LOCAL SCHEMA EXTRACTION (NO LLM) - Extract metadata before any LLM calls
 
2098
  print("πŸ” Extracting dataset schema locally (no LLM)...")
2099
  schema_info = extract_schema_local(file_path, sample_rows=3)
2100
 
@@ -2131,30 +2157,6 @@ You are a DOER. Complete workflows based on user intent."""
2131
  else:
2132
  system_prompt = self._build_system_prompt()
2133
 
2134
- # 🧠 RESOLVE AMBIGUITY USING SESSION MEMORY
2135
- original_file_path = file_path
2136
- original_target_col = target_col
2137
-
2138
- if self.session:
2139
- # Check if request has ambiguous references
2140
- resolved_params = self.session.resolve_ambiguity(task_description)
2141
-
2142
- # Use resolved params if user didn't specify
2143
- if not file_path or file_path == "":
2144
- if resolved_params.get("file_path"):
2145
- file_path = resolved_params["file_path"]
2146
- print(f"πŸ“ Using dataset from session: {file_path}")
2147
-
2148
- if not target_col:
2149
- if resolved_params.get("target_col"):
2150
- target_col = resolved_params["target_col"]
2151
- print(f"πŸ“ Using target column from session: {target_col}")
2152
-
2153
- # Show session context if available
2154
- if self.session.last_dataset or self.session.last_model:
2155
- context_summary = self.session.get_context_summary()
2156
- print(f"\n{context_summary}\n")
2157
-
2158
  # 🎯 PROACTIVE INTENT DETECTION - Tell LLM which tools to use BEFORE it tries wrong ones
2159
  task_lower = task_description.lower()
2160
 
 
2094
  """
2095
  start_time = time.time()
2096
 
2097
+ # 🧠 RESOLVE AMBIGUITY USING SESSION MEMORY (BEFORE SCHEMA EXTRACTION)
2098
+ # This ensures follow-up requests can find the file before we try to extract schema
2099
+ original_file_path = file_path
2100
+ original_target_col = target_col
2101
+
2102
+ if self.session:
2103
+ # Check if request has ambiguous references
2104
+ resolved_params = self.session.resolve_ambiguity(task_description)
2105
+
2106
+ # Use resolved params if user didn't specify
2107
+ if not file_path or file_path == "":
2108
+ if resolved_params.get("file_path"):
2109
+ file_path = resolved_params["file_path"]
2110
+ print(f"πŸ“ Using dataset from session: {file_path}")
2111
+
2112
+ if not target_col:
2113
+ if resolved_params.get("target_col"):
2114
+ target_col = resolved_params["target_col"]
2115
+ print(f"πŸ“ Using target column from session: {target_col}")
2116
+
2117
+ # Show session context if available
2118
+ if self.session.last_dataset or self.session.last_model:
2119
+ context_summary = self.session.get_context_summary()
2120
+ print(f"\n{context_summary}\n")
2121
+
2122
  # πŸš€ LOCAL SCHEMA EXTRACTION (NO LLM) - Extract metadata before any LLM calls
2123
+ # Now that file_path is resolved from session if needed
2124
  print("πŸ” Extracting dataset schema locally (no LLM)...")
2125
  schema_info = extract_schema_local(file_path, sample_rows=3)
2126
 
 
2157
  else:
2158
  system_prompt = self._build_system_prompt()
2159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2160
  # 🎯 PROACTIVE INTENT DETECTION - Tell LLM which tools to use BEFORE it tries wrong ones
2161
  task_lower = task_description.lower()
2162