Spaces:
Running
Running
Pulastya B
commited on
Commit
·
ff2d6c4
1
Parent(s):
296ce82
Fix progress bar to show latest step, visualizations in assets, model names, data files, and response formatting
Browse files- FRRONTEEEND/components/ChatInterface.tsx +69 -31
- src/orchestrator.py +33 -13
FRRONTEEEND/components/ChatInterface.tsx
CHANGED
|
@@ -88,11 +88,17 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
|
|
| 88 |
const progressData = await progressResponse.json();
|
| 89 |
const steps = progressData.steps || [];
|
| 90 |
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
}
|
| 97 |
}
|
| 98 |
} catch (err) {
|
|
@@ -694,69 +700,101 @@ export const ChatInterface: React.FC<{ onBack: () => void }> = ({ onBack }) => {
|
|
| 694 |
</div>
|
| 695 |
|
| 696 |
<div className="flex-1 overflow-y-auto p-4 space-y-4 custom-scrollbar">
|
| 697 |
-
{/* Collect all assets from messages */}
|
| 698 |
{(() => {
|
| 699 |
const allPlots: Array<{title: string, url: string, type?: string}> = [];
|
| 700 |
const allReports: Array<{name: string, path: string}> = [];
|
| 701 |
-
const
|
|
|
|
|
|
|
| 702 |
|
| 703 |
activeSession.messages.forEach(msg => {
|
| 704 |
if (msg.plots) allPlots.push(...msg.plots);
|
| 705 |
if (msg.reports) allReports.push(...msg.reports);
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
}
|
| 711 |
});
|
| 712 |
|
| 713 |
-
const
|
|
|
|
| 714 |
|
| 715 |
return (
|
| 716 |
<>
|
| 717 |
-
{/*
|
| 718 |
-
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 719 |
<div>
|
| 720 |
<div className="flex items-center gap-2 mb-3">
|
| 721 |
<FileText className="w-4 h-4 text-blue-400" />
|
| 722 |
-
<h4 className="text-xs font-bold uppercase tracking-wider text-white/60">
|
| 723 |
</div>
|
| 724 |
<div className="space-y-2">
|
| 725 |
-
{
|
| 726 |
<div
|
| 727 |
key={idx}
|
| 728 |
-
className="p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-
|
| 729 |
>
|
| 730 |
<div className="flex items-center justify-between">
|
| 731 |
-
<span className="text-sm text-white/80 truncate flex-1">{
|
| 732 |
-
<ChevronRight className="w-4 h-4 text-white/40 group-hover:text-
|
| 733 |
</div>
|
|
|
|
| 734 |
</div>
|
| 735 |
))}
|
| 736 |
</div>
|
| 737 |
</div>
|
| 738 |
)}
|
| 739 |
|
| 740 |
-
{/*
|
| 741 |
-
{
|
| 742 |
<div>
|
| 743 |
<div className="flex items-center gap-2 mb-3">
|
| 744 |
-
<
|
| 745 |
-
<h4 className="text-xs font-bold uppercase tracking-wider text-white/60">
|
| 746 |
</div>
|
| 747 |
<div className="space-y-2">
|
| 748 |
-
{
|
| 749 |
-
<
|
| 750 |
key={idx}
|
| 751 |
-
|
| 752 |
-
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"
|
| 753 |
>
|
| 754 |
<div className="flex items-center justify-between">
|
| 755 |
-
<span className="text-sm text-white/80 truncate flex-1">{
|
| 756 |
-
<ChevronRight className="w-4 h-4 text-white/40 group-hover:text-
|
| 757 |
</div>
|
| 758 |
-
|
| 759 |
-
</button>
|
| 760 |
))}
|
| 761 |
</div>
|
| 762 |
</div>
|
|
|
|
| 88 |
const progressData = await progressResponse.json();
|
| 89 |
const steps = progressData.steps || [];
|
| 90 |
|
| 91 |
+
if (steps.length > 0) {
|
| 92 |
+
const latestStep = steps[steps.length - 1];
|
| 93 |
+
const toolName = latestStep.tool
|
| 94 |
+
.replace(/_/g, ' ')
|
| 95 |
+
.replace(/generate/gi, 'Generating')
|
| 96 |
+
.replace(/train/gi, 'Training')
|
| 97 |
+
.replace(/clean/gi, 'Cleaning')
|
| 98 |
+
.replace(/create/gi, 'Creating')
|
| 99 |
+
.replace(/perform/gi, 'Performing')
|
| 100 |
+
.replace(/\b\w/g, (l: string) => l.toUpperCase());
|
| 101 |
+
setCurrentStep(toolName);
|
| 102 |
}
|
| 103 |
}
|
| 104 |
} catch (err) {
|
|
|
|
| 700 |
</div>
|
| 701 |
|
| 702 |
<div className="flex-1 overflow-y-auto p-4 space-y-4 custom-scrollbar">
|
|
|
|
| 703 |
{(() => {
|
| 704 |
const allPlots: Array<{title: string, url: string, type?: string}> = [];
|
| 705 |
const allReports: Array<{name: string, path: string}> = [];
|
| 706 |
+
const allDataFiles: string[] = [];
|
| 707 |
+
const baselineModels = ['xgboost', 'random_forest', 'catboost', 'lightgbm', 'ridge', 'lasso'];
|
| 708 |
+
const foundModels = new Set<string>();
|
| 709 |
|
| 710 |
activeSession.messages.forEach(msg => {
|
| 711 |
if (msg.plots) allPlots.push(...msg.plots);
|
| 712 |
if (msg.reports) allReports.push(...msg.reports);
|
| 713 |
+
|
| 714 |
+
baselineModels.forEach(model => {
|
| 715 |
+
if (msg.content.toLowerCase().includes(model)) {
|
| 716 |
+
const displayName = model.split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
| 717 |
+
foundModels.add(displayName);
|
| 718 |
+
}
|
| 719 |
+
});
|
| 720 |
+
|
| 721 |
+
if (msg.content.includes('Cleaned') || msg.content.includes('encoded')) {
|
| 722 |
+
allDataFiles.push('Cleaned & Encoded Dataset');
|
| 723 |
}
|
| 724 |
});
|
| 725 |
|
| 726 |
+
const uniqueDataFiles = [...new Set(allDataFiles)];
|
| 727 |
+
const uniqueModels = Array.from(foundModels);
|
| 728 |
|
| 729 |
return (
|
| 730 |
<>
|
| 731 |
+
{/* Plots Section FIRST */}
|
| 732 |
+
{allPlots.length > 0 && (
|
| 733 |
+
<div>
|
| 734 |
+
<div className="flex items-center gap-2 mb-3">
|
| 735 |
+
<BarChart3 className="w-4 h-4 text-emerald-400" />
|
| 736 |
+
<h4 className="text-xs font-bold uppercase tracking-wider text-white/60">Visualizations ({allPlots.length})</h4>
|
| 737 |
+
</div>
|
| 738 |
+
<div className="space-y-2">
|
| 739 |
+
{allPlots.map((plot, idx) => (
|
| 740 |
+
<button
|
| 741 |
+
key={idx}
|
| 742 |
+
onClick={() => setReportModalUrl(plot.url)}
|
| 743 |
+
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"
|
| 744 |
+
>
|
| 745 |
+
<div className="flex items-center justify-between">
|
| 746 |
+
<span className="text-sm text-white/80 truncate flex-1">{plot.title}</span>
|
| 747 |
+
<ChevronRight className="w-4 h-4 text-white/40 group-hover:text-emerald-400 transition-all" />
|
| 748 |
+
</div>
|
| 749 |
+
<span className="text-xs text-white/40 mt-1 block">{plot.type || 'interactive'}</span>
|
| 750 |
+
</button>
|
| 751 |
+
))}
|
| 752 |
+
</div>
|
| 753 |
+
</div>
|
| 754 |
+
)}
|
| 755 |
+
|
| 756 |
+
{/* Data Files Section */}
|
| 757 |
+
{uniqueDataFiles.length > 0 && (
|
| 758 |
<div>
|
| 759 |
<div className="flex items-center gap-2 mb-3">
|
| 760 |
<FileText className="w-4 h-4 text-blue-400" />
|
| 761 |
+
<h4 className="text-xs font-bold uppercase tracking-wider text-white/60">Data Files ({uniqueDataFiles.length})</h4>
|
| 762 |
</div>
|
| 763 |
<div className="space-y-2">
|
| 764 |
+
{uniqueDataFiles.map((file, idx) => (
|
| 765 |
<div
|
| 766 |
key={idx}
|
| 767 |
+
className="p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-blue-500/10 transition-all cursor-pointer group"
|
| 768 |
>
|
| 769 |
<div className="flex items-center justify-between">
|
| 770 |
+
<span className="text-sm text-white/80 truncate flex-1">{file}</span>
|
| 771 |
+
<ChevronRight className="w-4 h-4 text-white/40 group-hover:text-blue-400 transition-all" />
|
| 772 |
</div>
|
| 773 |
+
<span className="text-xs text-white/40 mt-1 block">Dataset</span>
|
| 774 |
</div>
|
| 775 |
))}
|
| 776 |
</div>
|
| 777 |
</div>
|
| 778 |
)}
|
| 779 |
|
| 780 |
+
{/* Models Section */}
|
| 781 |
+
{uniqueModels.length > 0 && (
|
| 782 |
<div>
|
| 783 |
<div className="flex items-center gap-2 mb-3">
|
| 784 |
+
<FileText className="w-4 h-4 text-purple-400" />
|
| 785 |
+
<h4 className="text-xs font-bold uppercase tracking-wider text-white/60">Models ({uniqueModels.length})</h4>
|
| 786 |
</div>
|
| 787 |
<div className="space-y-2">
|
| 788 |
+
{uniqueModels.map((model, idx) => (
|
| 789 |
+
<div
|
| 790 |
key={idx}
|
| 791 |
+
className="p-3 rounded-lg bg-white/5 border border-white/10 hover:bg-purple-500/10 transition-all cursor-pointer group"
|
|
|
|
| 792 |
>
|
| 793 |
<div className="flex items-center justify-between">
|
| 794 |
+
<span className="text-sm text-white/80 truncate flex-1">{model}</span>
|
| 795 |
+
<ChevronRight className="w-4 h-4 text-white/40 group-hover:text-purple-400 transition-all" />
|
| 796 |
</div>
|
| 797 |
+
</div>
|
|
|
|
| 798 |
))}
|
| 799 |
</div>
|
| 800 |
</div>
|
src/orchestrator.py
CHANGED
|
@@ -2305,21 +2305,41 @@ You are a DOER. Complete workflows based on user intent."""
|
|
| 2305 |
)
|
| 2306 |
summary_text = enhanced_summary["text"]
|
| 2307 |
|
| 2308 |
-
# 🧹 POST-PROCESS:
|
| 2309 |
import re
|
| 2310 |
-
|
| 2311 |
-
|
| 2312 |
-
summary_text = re.sub(r'
|
| 2313 |
-
summary_text = re.sub(r'outputs/[^\s\)]+', '
|
| 2314 |
-
|
| 2315 |
-
summary_text = re.sub(r'
|
| 2316 |
-
|
| 2317 |
-
|
| 2318 |
-
|
| 2319 |
-
summary_text = re.sub(r'\
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2320 |
summary_text = re.sub(r'`[^`]*\.(csv|pkl|html|png|json)[^`]*`', '', summary_text)
|
| 2321 |
-
|
| 2322 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2323 |
|
| 2324 |
metrics_data = enhanced_summary.get("metrics", {})
|
| 2325 |
artifacts_data = enhanced_summary.get("artifacts", {})
|
|
|
|
| 2305 |
)
|
| 2306 |
summary_text = enhanced_summary["text"]
|
| 2307 |
|
| 2308 |
+
# 🧹 POST-PROCESS: Aggressive cleanup of formatting
|
| 2309 |
import re
|
| 2310 |
+
|
| 2311 |
+
# Remove ALL file path patterns
|
| 2312 |
+
summary_text = re.sub(r'\./outputs/[^\s\)\]]+', '', summary_text)
|
| 2313 |
+
summary_text = re.sub(r'/outputs/[^\s\)\]]+', '', summary_text)
|
| 2314 |
+
summary_text = re.sub(r'outputs/[^\s\)\]]+', '', summary_text)
|
| 2315 |
+
summary_text = re.sub(r'\[[^\]]*\.(csv|pkl|html|png|json)[^\]]*\]', '', summary_text)
|
| 2316 |
+
|
| 2317 |
+
# Remove leftover file markers
|
| 2318 |
+
summary_text = re.sub(r'\[generated file\]', '', summary_text)
|
| 2319 |
+
summary_text = re.sub(r'\[see artifacts\]', '', summary_text)
|
| 2320 |
+
|
| 2321 |
+
# Remove file path mentions
|
| 2322 |
+
summary_text = re.sub(r'saved to:?\s*[^\s\.]+', '', summary_text, flags=re.IGNORECASE)
|
| 2323 |
+
summary_text = re.sub(r'output file:?\s*[^\s\.]+', '', summary_text, flags=re.IGNORECASE)
|
| 2324 |
+
summary_text = re.sub(r'file path:?\s*[^\s\.]+', '', summary_text, flags=re.IGNORECASE)
|
| 2325 |
+
summary_text = re.sub(r'path:?\s*[^\s\.]+', '', summary_text, flags=re.IGNORECASE)
|
| 2326 |
+
summary_text = re.sub(r'directory:?\s*[^\s\.]+', '', summary_text, flags=re.IGNORECASE)
|
| 2327 |
+
|
| 2328 |
+
# Remove backtick-wrapped paths and parenthetical paths
|
| 2329 |
summary_text = re.sub(r'`[^`]*\.(csv|pkl|html|png|json)[^`]*`', '', summary_text)
|
| 2330 |
+
summary_text = re.sub(r'\([^\)]*\.(csv|pkl|html|png|json)[^\)]*\)', '', summary_text)
|
| 2331 |
+
|
| 2332 |
+
# Clean broken tables
|
| 2333 |
+
summary_text = re.sub(r'\|\s*\[[^\]]*\]\s*\|', '|', summary_text)
|
| 2334 |
+
summary_text = re.sub(r'\|\s*`[^`]*`\s*\|', '|', summary_text)
|
| 2335 |
+
summary_text = re.sub(r'\|\s*\|', '', summary_text)
|
| 2336 |
+
|
| 2337 |
+
# Clean excessive whitespace
|
| 2338 |
+
summary_text = re.sub(r'\n\n\n+', '\n\n', summary_text)
|
| 2339 |
+
summary_text = re.sub(r'[ \t]+', ' ', summary_text) # Remove extra spaces
|
| 2340 |
+
|
| 2341 |
+
# Remove code blocks that are just paths
|
| 2342 |
+
summary_text = re.sub(r'`\.?/?[\w\-/\.]*\.(csv|pkl|html|png|json)`', '', summary_text)
|
| 2343 |
|
| 2344 |
metrics_data = enhanced_summary.get("metrics", {})
|
| 2345 |
artifacts_data = enhanced_summary.get("artifacts", {})
|