abir-hr196 commited on
Commit
0e1846b
Β·
1 Parent(s): f35a40c
Files changed (2) hide show
  1. app.py +87 -7
  2. tinysql_dataset_viewer.py +224 -44
app.py CHANGED
@@ -7,6 +7,7 @@ custom_css = """
7
  --martian-orange: #FF6B4A;
8
  --martian-black: #0A0A0A;
9
  --martian-gray-dark: #1A1A1A;
 
10
  }
11
 
12
  .gradio-container {
@@ -14,29 +15,108 @@ custom_css = """
14
  background-color: var(--martian-black) !important;
15
  }
16
 
 
 
 
 
 
 
 
 
17
  .tab-nav button {
18
- font-size: 1.1rem !important;
19
  font-weight: 600 !important;
20
  padding: 0.75rem 1.5rem !important;
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
  .tab-nav button.selected {
24
- border-bottom: 3px solid var(--martian-orange) !important;
25
- color: var(--martian-orange) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
  """
28
 
29
- with gr.Blocks(css=custom_css, title="TinySQL Demo") as demo:
 
 
 
 
 
 
 
 
 
30
  # Shared state for passing data between tabs
31
  shared_instruction = gr.State("")
32
  shared_schema = gr.State("")
33
 
34
  with gr.Tabs():
35
- with gr.Tab("Dataset Viewer"):
36
  viewer_components = dataset_viewer(shared_instruction, shared_schema)
37
 
38
- with gr.Tab("Model Demo"):
39
  model_components = model_demo(shared_instruction, shared_schema)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  if __name__ == "__main__":
42
- demo.launch()
 
7
  --martian-orange: #FF6B4A;
8
  --martian-black: #0A0A0A;
9
  --martian-gray-dark: #1A1A1A;
10
+ --martian-gray-medium: #2A2A2A;
11
  }
12
 
13
  .gradio-container {
 
15
  background-color: var(--martian-black) !important;
16
  }
17
 
18
+ /* Cute HuggingFace-style tabs */
19
+ .tab-nav {
20
+ border-bottom: 2px solid var(--martian-gray-dark) !important;
21
+ background: var(--martian-gray-dark) !important;
22
+ padding: 0.5rem 1rem !important;
23
+ border-radius: 12px 12px 0 0 !important;
24
+ }
25
+
26
  .tab-nav button {
27
+ font-size: 1rem !important;
28
  font-weight: 600 !important;
29
  padding: 0.75rem 1.5rem !important;
30
+ border-radius: 8px !important;
31
+ margin: 0 0.25rem !important;
32
+ transition: all 0.3s ease !important;
33
+ color: #888 !important;
34
+ }
35
+
36
+ .tab-nav button:hover {
37
+ background: var(--martian-gray-medium) !important;
38
+ color: #E0E0E0 !important;
39
  }
40
 
41
  .tab-nav button.selected {
42
+ background: var(--martian-orange) !important;
43
+ color: white !important;
44
+ box-shadow: 0 2px 8px rgba(255, 107, 74, 0.3) !important;
45
+ }
46
+
47
+ /* Cute footer */
48
+ .footer {
49
+ text-align: center;
50
+ padding: 2rem 0;
51
+ margin-top: 3rem;
52
+ border-top: 2px solid var(--martian-gray-dark);
53
+ background: var(--martian-gray-dark);
54
+ border-radius: 12px;
55
+ }
56
+
57
+ .footer-logo {
58
+ width: 120px;
59
+ margin-bottom: 1rem;
60
+ opacity: 0.9;
61
+ transition: opacity 0.3s ease;
62
+ }
63
+
64
+ .footer-logo:hover {
65
+ opacity: 1;
66
+ }
67
+
68
+ .footer-text {
69
+ color: #999;
70
+ font-size: 0.95rem;
71
+ margin: 0.5rem 0;
72
+ }
73
+
74
+ .footer-text .heart {
75
+ color: var(--martian-orange);
76
+ animation: heartbeat 1.5s ease-in-out infinite;
77
+ }
78
+
79
+ @keyframes heartbeat {
80
+ 0%, 100% { transform: scale(1); }
81
+ 50% { transform: scale(1.1); }
82
  }
83
  """
84
 
85
+ with gr.Blocks(css=custom_css, title="TinySQL Demo", theme=gr.themes.Soft()) as demo:
86
+ # Martian Logo Header
87
+ gr.HTML("""
88
+ <div style="text-align: center; padding: 2rem 0 1rem 0;">
89
+ <img src="https://withmartian.com/logo.png" alt="Martian" style="height: 60px; margin-bottom: 1rem;" onerror="this.style.display='none'">
90
+ <h1 style="font-size: 2.5rem; font-weight: 700; color: #FF6B4A; margin: 0;">TinySQL</h1>
91
+ <p style="color: #999; font-size: 1.1rem; margin-top: 0.5rem;">Mechanistic Interpretability for Text-to-SQL</p>
92
+ </div>
93
+ """)
94
+
95
  # Shared state for passing data between tabs
96
  shared_instruction = gr.State("")
97
  shared_schema = gr.State("")
98
 
99
  with gr.Tabs():
100
+ with gr.Tab("πŸ“Š Dataset Viewer"):
101
  viewer_components = dataset_viewer(shared_instruction, shared_schema)
102
 
103
+ with gr.Tab("πŸ€– Model Demo"):
104
  model_components = model_demo(shared_instruction, shared_schema)
105
+
106
+ # Footer with Martian branding
107
+ gr.HTML("""
108
+ <div class="footer">
109
+ <img src="https://withmartian.com/logo.png" alt="Martian" class="footer-logo" onerror="this.style.display='none'">
110
+ <p class="footer-text">
111
+ Brought to you with <span class="heart">❀️</span> from the Martian science team
112
+ </p>
113
+ <p class="footer-text" style="font-size: 0.85rem; margin-top: 1rem;">
114
+ <a href="https://arxiv.org/abs/2503.12730" style="color: #FF6B4A; text-decoration: none;">πŸ“„ Paper</a> β€’
115
+ <a href="https://github.com/withmartian/TinySQL" style="color: #FF6B4A; text-decoration: none;">πŸ’» Code</a> β€’
116
+ <a href="https://huggingface.co/collections/withmartian/tinysql-6760e92748b63fa56a6ffc9f" style="color: #FF6B4A; text-decoration: none;">πŸ€— Dataset</a>
117
+ </p>
118
+ </div>
119
+ """)
120
 
121
  if __name__ == "__main__":
122
+ demo.launch(ssr_mode=False)
tinysql_dataset_viewer.py CHANGED
@@ -2,7 +2,6 @@ import gradio as gr
2
  from datasets import load_dataset
3
  import pandas as pd
4
 
5
- # Datasets to include
6
  DATASETS = {
7
  "CS1": "withmartian/cs1_dataset",
8
  "CS2": "withmartian/cs2_dataset",
@@ -15,11 +14,9 @@ DATASETS = {
15
  COLUMNS = ["create_statement", "english_prompt", "sql_statement"]
16
 
17
  def load_preview(dataset_name):
18
- """Load first 500 rows of selected dataset"""
19
  try:
20
  ds = load_dataset(DATASETS[dataset_name], split="train")
21
  df = pd.DataFrame(ds).head(500)
22
- # Filter to only the columns we want
23
  if all(col in df.columns for col in COLUMNS):
24
  df = df[COLUMNS]
25
  return df
@@ -27,7 +24,6 @@ def load_preview(dataset_name):
27
  return pd.DataFrame({"Error": [str(e)]})
28
 
29
  def filter_dataframe(df, search_query):
30
- """Filter dataframe by search query across all columns"""
31
  if not search_query or df.empty or "Error" in df.columns:
32
  return df
33
 
@@ -37,64 +33,251 @@ def filter_dataframe(df, search_query):
37
  )
38
  return df[mask]
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  def dataset_viewer(shared_instruction, shared_schema):
41
- """Dataset viewer component with ability to send examples to model demo"""
42
-
43
  gr.HTML("""
44
- <div class="header-section" style="text-align: center; padding: 2.5rem 1.5rem; background: linear-gradient(135deg, #1A1A1A 0%, #2A2A2A 100%); border-radius: 16px; margin-bottom: 2rem; color: white;">
45
- <h1 style="font-size: 2.2rem; font-weight: 700; margin-bottom: 0.75rem;">TinySQL Dataset Viewer</h1>
46
- <p style="font-size: 1.1rem; opacity: 0.9; line-height: 1.6;">
47
- Browse dataset previews, search, and filter queries with <span style="color: #FF6B4A; font-weight: 600;">ease</span>
48
  </p>
49
  </div>
50
  """)
51
 
52
  gr.HTML("""
53
- <div class="info-box" style="background: #3A3A3A; border-radius: 12px; padding: 1.5rem; margin: 1.5rem 0; border-left: 4px solid #FF6B4A; color: #E0E0E0;">
54
- <strong>Preview Mode:</strong> Showing first 500 rows of each dataset. Use search to filter results in real-time.
 
55
  </div>
56
  """)
57
 
58
  with gr.Row():
59
  with gr.Column(scale=1):
60
- gr.Markdown("### Dataset Selection")
 
61
  dataset_dropdown = gr.Dropdown(
62
  choices=list(DATASETS.keys()),
63
  value="CS1",
64
  label="Choose Dataset",
65
- info="Select a dataset to preview"
66
  )
67
 
68
  gr.HTML("""
69
- <div style="background: #3A3A3A; border-radius: 8px; padding: 1rem; margin-top: 1rem; font-size: 0.9rem; color: #D0D0D0;">
70
- <strong>Complexity Levels:</strong><br><br>
71
- <strong>CS1:</strong> Basic SELECT-FROM<br>
72
- <strong>CS2:</strong> Adds ORDER BY<br>
73
- <strong>CS3:</strong> Aggregations<br>
74
- <strong>CS4:</strong> Adds WHERE filters<br><br>
75
- <strong>Synonyms:</strong> Natural language variations
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  </div>
77
  """)
78
 
79
- load_btn = gr.Button("Load Dataset", variant="primary", size="lg")
80
 
 
81
  row_selector = gr.Number(
82
- label="Select Row to Test",
83
  value=0,
84
  minimum=0,
85
  precision=0,
86
- info="Enter row number to send to Model Demo"
87
  )
88
 
89
- send_to_model_btn = gr.Button("πŸš€ Run This Example in Model Demo", variant="primary")
90
 
91
  with gr.Column(scale=3):
92
- gr.Markdown("### Dataset Preview (First 500 Rows)")
93
 
94
  search_box = gr.Textbox(
95
- label="Search",
96
  placeholder="Search across all columns...",
97
- lines=1
 
98
  )
99
 
100
  df_display = gr.Dataframe(
@@ -102,20 +285,22 @@ def dataset_viewer(shared_instruction, shared_schema):
102
  datatype=["str", "str", "str"],
103
  interactive=False,
104
  wrap=True,
105
- label="Results"
 
106
  )
107
 
108
- stats_display = gr.Markdown("Click 'Load Dataset' to begin")
 
 
 
109
 
110
- # Store the loaded dataframe
111
  df_state = gr.State(value=pd.DataFrame())
112
 
113
- # Load dataset
114
  def load_and_display(dataset_name):
115
  df = load_preview(dataset_name)
116
  if "Error" in df.columns:
117
  return df, df, "❌ Error loading dataset"
118
- stats = f"**Loaded:** {len(df)} rows | **Columns:** {', '.join(COLUMNS)}"
119
  return df, df, stats
120
 
121
  load_btn.click(
@@ -124,15 +309,14 @@ def dataset_viewer(shared_instruction, shared_schema):
124
  outputs=[df_state, df_display, stats_display]
125
  )
126
 
127
- # Search functionality
128
  def search_and_display(df, query):
129
  if df.empty:
130
- return df, "Load a dataset first"
131
 
132
  filtered_df = filter_dataframe(df, query)
133
- stats = f"**Showing:** {len(filtered_df)} of {len(df)} rows"
134
  if query:
135
- stats += f" | **Search:** '{query}'"
136
  return filtered_df, stats
137
 
138
  search_box.change(
@@ -141,16 +325,15 @@ def dataset_viewer(shared_instruction, shared_schema):
141
  outputs=[df_display, stats_display]
142
  )
143
 
144
- # Send example to model demo
145
  def send_to_model(df, row_num):
146
  if df.empty or row_num >= len(df):
147
- return "", "", "⚠️ Invalid row number or no data loaded"
148
 
149
  row = df.iloc[int(row_num)]
150
  instruction = row['english_prompt'] if 'english_prompt' in row else ""
151
  schema = row['create_statement'] if 'create_statement' in row else ""
152
 
153
- return instruction, schema, f"βœ… Row {row_num} loaded! Switch to Model Demo tab."
154
 
155
  send_to_model_btn.click(
156
  fn=send_to_model,
@@ -158,7 +341,4 @@ def dataset_viewer(shared_instruction, shared_schema):
158
  outputs=[shared_instruction, shared_schema, stats_display]
159
  )
160
 
161
- return {
162
- 'df_state': df_state,
163
- 'df_display': df_display
164
- }
 
2
  from datasets import load_dataset
3
  import pandas as pd
4
 
 
5
  DATASETS = {
6
  "CS1": "withmartian/cs1_dataset",
7
  "CS2": "withmartian/cs2_dataset",
 
14
  COLUMNS = ["create_statement", "english_prompt", "sql_statement"]
15
 
16
  def load_preview(dataset_name):
 
17
  try:
18
  ds = load_dataset(DATASETS[dataset_name], split="train")
19
  df = pd.DataFrame(ds).head(500)
 
20
  if all(col in df.columns for col in COLUMNS):
21
  df = df[COLUMNS]
22
  return df
 
24
  return pd.DataFrame({"Error": [str(e)]})
25
 
26
  def filter_dataframe(df, search_query):
 
27
  if not search_query or df.empty or "Error" in df.columns:
28
  return df
29
 
 
33
  )
34
  return df[mask]
35
 
36
+ # HuggingFace-style CSS
37
+ hf_style_css = """
38
+ /* HuggingFace-inspired table styling */
39
+ .dataframe-container {
40
+ border-radius: 12px !important;
41
+ overflow: hidden !important;
42
+ border: 1px solid #2A2A2A !important;
43
+ background: #1A1A1A !important;
44
+ }
45
+
46
+ .dataframe table {
47
+ border-collapse: separate !important;
48
+ border-spacing: 0 !important;
49
+ width: 100% !important;
50
+ }
51
+
52
+ .dataframe thead {
53
+ background: linear-gradient(135deg, #2A2A2A 0%, #3A3A3A 100%) !important;
54
+ position: sticky !important;
55
+ top: 0 !important;
56
+ z-index: 10 !important;
57
+ }
58
+
59
+ .dataframe thead th {
60
+ color: #FF6B4A !important;
61
+ font-weight: 600 !important;
62
+ text-align: left !important;
63
+ padding: 1rem !important;
64
+ border-bottom: 2px solid #FF6B4A !important;
65
+ font-size: 0.9rem !important;
66
+ text-transform: uppercase !important;
67
+ letter-spacing: 0.5px !important;
68
+ }
69
+
70
+ .dataframe tbody tr {
71
+ background: #1A1A1A !important;
72
+ transition: all 0.2s ease !important;
73
+ border-bottom: 1px solid #2A2A2A !important;
74
+ }
75
+
76
+ .dataframe tbody tr:hover {
77
+ background: #2A2A2A !important;
78
+ box-shadow: 0 2px 8px rgba(255, 107, 74, 0.1) !important;
79
+ transform: scale(1.01) !important;
80
+ }
81
+
82
+ .dataframe tbody td {
83
+ padding: 0.75rem 1rem !important;
84
+ color: #D0D0D0 !important;
85
+ font-size: 0.9rem !important;
86
+ line-height: 1.5 !important;
87
+ }
88
+
89
+ .dataframe tbody tr:nth-child(even) {
90
+ background: #181818 !important;
91
+ }
92
+
93
+ .dataframe tbody tr:nth-child(even):hover {
94
+ background: #2A2A2A !important;
95
+ }
96
+
97
+ /* Cute badges for dataset types */
98
+ .dataset-badge {
99
+ display: inline-block;
100
+ padding: 0.25rem 0.75rem;
101
+ border-radius: 12px;
102
+ font-size: 0.8rem;
103
+ font-weight: 600;
104
+ margin: 0.25rem;
105
+ }
106
+
107
+ .badge-basic {
108
+ background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
109
+ color: white;
110
+ }
111
+
112
+ .badge-medium {
113
+ background: linear-gradient(135deg, #FF9800 0%, #F57C00 100%);
114
+ color: white;
115
+ }
116
+
117
+ .badge-advanced {
118
+ background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);
119
+ color: white;
120
+ }
121
+
122
+ /* Cute info boxes */
123
+ .cute-info-box {
124
+ background: linear-gradient(135deg, #2A2A2A 0%, #3A3A3A 100%);
125
+ border-radius: 16px;
126
+ padding: 1.5rem;
127
+ margin: 1rem 0;
128
+ border: 2px solid #FF6B4A;
129
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.15);
130
+ position: relative;
131
+ overflow: hidden;
132
+ }
133
+
134
+ .cute-info-box::before {
135
+ content: '';
136
+ position: absolute;
137
+ top: 0;
138
+ left: 0;
139
+ width: 4px;
140
+ height: 100%;
141
+ background: linear-gradient(180deg, #FF6B4A 0%, #FF5733 100%);
142
+ }
143
+
144
+ .cute-info-box h3 {
145
+ color: #FF6B4A;
146
+ font-size: 1.1rem;
147
+ margin-bottom: 0.5rem;
148
+ font-weight: 600;
149
+ }
150
+
151
+ .cute-info-box p {
152
+ color: #D0D0D0;
153
+ line-height: 1.6;
154
+ margin: 0;
155
+ }
156
+
157
+ /* Loading animation */
158
+ .loading {
159
+ display: inline-block;
160
+ width: 20px;
161
+ height: 20px;
162
+ border: 3px solid #3A3A3A;
163
+ border-top: 3px solid #FF6B4A;
164
+ border-radius: 50%;
165
+ animation: spin 1s linear infinite;
166
+ }
167
+
168
+ @keyframes spin {
169
+ 0% { transform: rotate(0deg); }
170
+ 100% { transform: rotate(360deg); }
171
+ }
172
+
173
+ /* Cute buttons */
174
+ .cute-button {
175
+ background: linear-gradient(135deg, #FF6B4A 0%, #FF5733 100%) !important;
176
+ border: none !important;
177
+ border-radius: 12px !important;
178
+ padding: 0.75rem 1.5rem !important;
179
+ font-weight: 600 !important;
180
+ color: white !important;
181
+ box-shadow: 0 4px 12px rgba(255, 107, 74, 0.3) !important;
182
+ transition: all 0.3s ease !important;
183
+ }
184
+
185
+ .cute-button:hover {
186
+ transform: translateY(-2px) !important;
187
+ box-shadow: 0 6px 16px rgba(255, 107, 74, 0.4) !important;
188
+ }
189
+
190
+ /* Search box */
191
+ .search-box input {
192
+ background: #2A2A2A !important;
193
+ border: 2px solid #3A3A3A !important;
194
+ border-radius: 12px !important;
195
+ padding: 0.75rem !important;
196
+ color: #E0E0E0 !important;
197
+ transition: all 0.3s ease !important;
198
+ }
199
+
200
+ .search-box input:focus {
201
+ border-color: #FF6B4A !important;
202
+ box-shadow: 0 0 0 3px rgba(255, 107, 74, 0.1) !important;
203
+ }
204
+ """
205
+
206
  def dataset_viewer(shared_instruction, shared_schema):
 
 
207
  gr.HTML("""
208
+ <div style="text-align: center; padding: 2rem 1.5rem; background: linear-gradient(135deg, #2A2A2A 0%, #3A3A3A 100%); border-radius: 16px; margin-bottom: 1.5rem; box-shadow: 0 4px 12px rgba(0,0,0,0.3);">
209
+ <h2 style="font-size: 2rem; font-weight: 700; margin-bottom: 0.5rem; color: #FF6B4A;">πŸ“Š Dataset Explorer</h2>
210
+ <p style="font-size: 1rem; opacity: 0.9; line-height: 1.6; color: #D0D0D0;">
211
+ Browse, search, and explore TinySQL datasets
212
  </p>
213
  </div>
214
  """)
215
 
216
  gr.HTML("""
217
+ <div class="cute-info-box">
218
+ <h3>🎯 Quick Start</h3>
219
+ <p>Select a dataset, click "Load Dataset", then use search to filter. Pick any row and send it to the Model Demo tab!</p>
220
  </div>
221
  """)
222
 
223
  with gr.Row():
224
  with gr.Column(scale=1):
225
+ gr.Markdown("### πŸŽ›οΈ Controls")
226
+
227
  dataset_dropdown = gr.Dropdown(
228
  choices=list(DATASETS.keys()),
229
  value="CS1",
230
  label="Choose Dataset",
231
+ info="Select complexity level"
232
  )
233
 
234
  gr.HTML("""
235
+ <div style="background: #2A2A2A; border-radius: 12px; padding: 1.25rem; margin: 1rem 0; border: 1px solid #3A3A3A;">
236
+ <h4 style="color: #FF6B4A; font-size: 0.95rem; margin-bottom: 1rem;">Dataset Levels</h4>
237
+ <div style="margin: 0.5rem 0;">
238
+ <span class="dataset-badge badge-basic">CS1</span>
239
+ <span style="color: #999; font-size: 0.85rem; margin-left: 0.5rem;">Basic SELECT</span>
240
+ </div>
241
+ <div style="margin: 0.5rem 0;">
242
+ <span class="dataset-badge badge-basic">CS2</span>
243
+ <span style="color: #999; font-size: 0.85rem; margin-left: 0.5rem;">+ ORDER BY</span>
244
+ </div>
245
+ <div style="margin: 0.5rem 0;">
246
+ <span class="dataset-badge badge-medium">CS3</span>
247
+ <span style="color: #999; font-size: 0.85rem; margin-left: 0.5rem;">+ Aggregations</span>
248
+ </div>
249
+ <div style="margin: 0.5rem 0;">
250
+ <span class="dataset-badge badge-advanced">CS4</span>
251
+ <span style="color: #999; font-size: 0.85rem; margin-left: 0.5rem;">+ WHERE filters</span>
252
+ </div>
253
+ <div style="margin: 0.5rem 0; padding-top: 0.5rem; border-top: 1px solid #3A3A3A;">
254
+ <span style="color: #FF6B4A; font-size: 0.85rem;">✨ Synonyms</span>
255
+ <span style="color: #999; font-size: 0.85rem; margin-left: 0.5rem;">Natural variations</span>
256
+ </div>
257
  </div>
258
  """)
259
 
260
+ load_btn = gr.Button("πŸ“₯ Load Dataset", variant="primary", size="lg", elem_classes="cute-button")
261
 
262
+ gr.Markdown("### 🎯 Test Example")
263
  row_selector = gr.Number(
264
+ label="Row Number",
265
  value=0,
266
  minimum=0,
267
  precision=0,
268
+ info="Pick a row to test"
269
  )
270
 
271
+ send_to_model_btn = gr.Button("πŸš€ Run in Model Demo", variant="primary", elem_classes="cute-button")
272
 
273
  with gr.Column(scale=3):
274
+ gr.Markdown("### πŸ“‹ Dataset Preview")
275
 
276
  search_box = gr.Textbox(
277
+ label="πŸ” Search",
278
  placeholder="Search across all columns...",
279
+ lines=1,
280
+ elem_classes="search-box"
281
  )
282
 
283
  df_display = gr.Dataframe(
 
285
  datatype=["str", "str", "str"],
286
  interactive=False,
287
  wrap=True,
288
+ label="Results",
289
+ elem_classes="dataframe-container"
290
  )
291
 
292
+ stats_display = gr.Markdown(
293
+ "πŸ‘† Click **Load Dataset** to begin exploring",
294
+ elem_classes="stats-info"
295
+ )
296
 
 
297
  df_state = gr.State(value=pd.DataFrame())
298
 
 
299
  def load_and_display(dataset_name):
300
  df = load_preview(dataset_name)
301
  if "Error" in df.columns:
302
  return df, df, "❌ Error loading dataset"
303
+ stats = f"βœ… **Loaded {len(df)} rows** β€’ {', '.join(COLUMNS)}"
304
  return df, df, stats
305
 
306
  load_btn.click(
 
309
  outputs=[df_state, df_display, stats_display]
310
  )
311
 
 
312
  def search_and_display(df, query):
313
  if df.empty:
314
+ return df, "⚠️ Load a dataset first"
315
 
316
  filtered_df = filter_dataframe(df, query)
317
+ stats = f"πŸ“Š **Showing {len(filtered_df)} of {len(df)} rows**"
318
  if query:
319
+ stats += f" β€’ πŸ” Search: '{query}'"
320
  return filtered_df, stats
321
 
322
  search_box.change(
 
325
  outputs=[df_display, stats_display]
326
  )
327
 
 
328
  def send_to_model(df, row_num):
329
  if df.empty or row_num >= len(df):
330
+ return "", "", "⚠️ Invalid row or no data loaded"
331
 
332
  row = df.iloc[int(row_num)]
333
  instruction = row['english_prompt'] if 'english_prompt' in row else ""
334
  schema = row['create_statement'] if 'create_statement' in row else ""
335
 
336
+ return instruction, schema, f"βœ… **Row {row_num} loaded!** Switch to Model Demo tab πŸ‘‰"
337
 
338
  send_to_model_btn.click(
339
  fn=send_to_model,
 
341
  outputs=[shared_instruction, shared_schema, stats_display]
342
  )
343
 
344
+ return {'df_state': df_state, 'df_display': df_display}