Spaces:
Running on Zero
Running on Zero
DataSense progress bar HTML, replace slider and model jargon
Browse files
app.py
CHANGED
|
@@ -91,7 +91,37 @@ CUSTOM_CSS = """
|
|
| 91 |
color: var(--ds-accent);
|
| 92 |
margin: 0 0 0.35rem 0;
|
| 93 |
}
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
#ds-results .tabitem { padding-top: 0.75rem !important; }
|
| 96 |
.ds-answer-card {
|
| 97 |
background: linear-gradient(145deg, #122a2a 0%, #151c26 100%);
|
|
@@ -245,15 +275,30 @@ def _wrap_trace(trace: str) -> str:
|
|
| 245 |
return f'<div class="ds-trace-wrap">\n\n{trace}\n\n</div>'
|
| 246 |
|
| 247 |
|
| 248 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
return (
|
| 250 |
-
|
| 251 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
_wrap_trace(trace),
|
| 253 |
answer,
|
| 254 |
)
|
| 255 |
|
| 256 |
|
|
|
|
|
|
|
|
|
|
| 257 |
@spaces.GPU(duration=180)
|
| 258 |
def run_task(
|
| 259 |
data_mode: str,
|
|
@@ -264,10 +309,10 @@ def run_task(
|
|
| 264 |
progress=gr.Progress(),
|
| 265 |
):
|
| 266 |
if not task.strip():
|
| 267 |
-
yield _progress_update(
|
| 268 |
return
|
| 269 |
|
| 270 |
-
yield _progress_update(5, "
|
| 271 |
data_path = _resolve_data_path(data_mode, dataset_name, upload_file)
|
| 272 |
if data_path is None:
|
| 273 |
msg = "⚠️ Upload a `.csv` or `.xlsx` file first." if data_mode == "Upload your file" else f"⚠️ Dataset not found: {dataset_name}"
|
|
@@ -275,11 +320,11 @@ def run_task(
|
|
| 275 |
return
|
| 276 |
|
| 277 |
try:
|
| 278 |
-
yield _progress_update(12, "Loading
|
| 279 |
-
progress(0.15, desc="Loading
|
| 280 |
model, tokenizer = _load_model()
|
| 281 |
|
| 282 |
-
yield _progress_update(22, "
|
| 283 |
agent_stream = run_agent(
|
| 284 |
model,
|
| 285 |
tokenizer,
|
|
@@ -296,7 +341,7 @@ def run_task(
|
|
| 296 |
pct = int(22 + (73 * step / max(total, 1)))
|
| 297 |
yield _progress_update(
|
| 298 |
pct,
|
| 299 |
-
f"
|
| 300 |
trace_md,
|
| 301 |
"",
|
| 302 |
)
|
|
@@ -305,7 +350,7 @@ def run_task(
|
|
| 305 |
answer_html = _format_answer_html(result.get("answer", ""), result.get("summary", ""))
|
| 306 |
yield _progress_update(
|
| 307 |
100,
|
| 308 |
-
"
|
| 309 |
result["steps_markdown"],
|
| 310 |
answer_html,
|
| 311 |
)
|
|
@@ -390,16 +435,7 @@ def build_ui() -> gr.Blocks:
|
|
| 390 |
|
| 391 |
with gr.Column(scale=7, elem_id="ds-results"):
|
| 392 |
gr.Markdown("### Results")
|
| 393 |
-
|
| 394 |
-
progress_bar = gr.Slider(
|
| 395 |
-
minimum=0,
|
| 396 |
-
maximum=100,
|
| 397 |
-
value=0,
|
| 398 |
-
step=1,
|
| 399 |
-
label="Run progress",
|
| 400 |
-
interactive=False,
|
| 401 |
-
elem_id="ds-progress-bar",
|
| 402 |
-
)
|
| 403 |
with gr.Tabs():
|
| 404 |
with gr.Tab("🔍 Execution trace", id="trace_tab"):
|
| 405 |
steps_out = gr.Markdown()
|
|
@@ -416,7 +452,7 @@ def build_ui() -> gr.Blocks:
|
|
| 416 |
run_btn.click(
|
| 417 |
fn=run_task,
|
| 418 |
inputs=[data_mode, dataset, upload, task, max_steps],
|
| 419 |
-
outputs=[
|
| 420 |
show_progress="hidden",
|
| 421 |
)
|
| 422 |
|
|
|
|
| 91 |
color: var(--ds-accent);
|
| 92 |
margin: 0 0 0.35rem 0;
|
| 93 |
}
|
| 94 |
+
.ds-progress-wrap {
|
| 95 |
+
margin: 0 0 1rem 0;
|
| 96 |
+
padding: 0.85rem 1rem;
|
| 97 |
+
background: #0f1419;
|
| 98 |
+
border: 1px solid #2a3544;
|
| 99 |
+
border-radius: 10px;
|
| 100 |
+
}
|
| 101 |
+
.ds-progress-text {
|
| 102 |
+
font-family: 'IBM Plex Mono', monospace;
|
| 103 |
+
font-size: 0.82rem;
|
| 104 |
+
color: #3ecfae;
|
| 105 |
+
margin-bottom: 0.55rem;
|
| 106 |
+
line-height: 1.4;
|
| 107 |
+
}
|
| 108 |
+
.ds-progress-text .ds-pct {
|
| 109 |
+
color: #8b9cb3;
|
| 110 |
+
font-size: 0.75rem;
|
| 111 |
+
}
|
| 112 |
+
.ds-progress-track {
|
| 113 |
+
height: 6px;
|
| 114 |
+
background: #1a2330;
|
| 115 |
+
border-radius: 999px;
|
| 116 |
+
overflow: hidden;
|
| 117 |
+
}
|
| 118 |
+
.ds-progress-fill {
|
| 119 |
+
height: 100%;
|
| 120 |
+
background: linear-gradient(90deg, #1f6f5c, #3ecfae);
|
| 121 |
+
border-radius: 999px;
|
| 122 |
+
transition: width 0.35s ease;
|
| 123 |
+
}
|
| 124 |
+
.ds-progress-wrap.ds-idle .ds-progress-track { display: none; }
|
| 125 |
#ds-results .tabitem { padding-top: 0.75rem !important; }
|
| 126 |
.ds-answer-card {
|
| 127 |
background: linear-gradient(145deg, #122a2a 0%, #151c26 100%);
|
|
|
|
| 275 |
return f'<div class="ds-trace-wrap">\n\n{trace}\n\n</div>'
|
| 276 |
|
| 277 |
|
| 278 |
+
def _progress_html(pct: int | None, label: str) -> str:
|
| 279 |
+
safe_label = html.escape(label)
|
| 280 |
+
if pct is None:
|
| 281 |
+
return f'<div class="ds-progress-wrap ds-idle"><div class="ds-progress-text">{safe_label}</div></div>'
|
| 282 |
+
pct = max(0, min(100, pct))
|
| 283 |
return (
|
| 284 |
+
f'<div class="ds-progress-wrap">'
|
| 285 |
+
f'<div class="ds-progress-text">{safe_label} <span class="ds-pct">{pct}%</span></div>'
|
| 286 |
+
f'<div class="ds-progress-track"><div class="ds-progress-fill" style="width:{pct}%"></div></div>'
|
| 287 |
+
f"</div>"
|
| 288 |
+
)
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def _progress_update(pct: int | None, label: str, trace: str = "", answer: str = ""):
|
| 292 |
+
return (
|
| 293 |
+
_progress_html(pct, label),
|
| 294 |
_wrap_trace(trace),
|
| 295 |
answer,
|
| 296 |
)
|
| 297 |
|
| 298 |
|
| 299 |
+
IDLE_PROGRESS_HTML = _progress_html(None, "Ready — click Run DataSense")
|
| 300 |
+
|
| 301 |
+
|
| 302 |
@spaces.GPU(duration=180)
|
| 303 |
def run_task(
|
| 304 |
data_mode: str,
|
|
|
|
| 309 |
progress=gr.Progress(),
|
| 310 |
):
|
| 311 |
if not task.strip():
|
| 312 |
+
yield _progress_update(None, "Enter a question to run DataSense", "", '<div class="ds-answer-empty">Enter a task question.</div>')
|
| 313 |
return
|
| 314 |
|
| 315 |
+
yield _progress_update(5, "Reading your dataset…")
|
| 316 |
data_path = _resolve_data_path(data_mode, dataset_name, upload_file)
|
| 317 |
if data_path is None:
|
| 318 |
msg = "⚠️ Upload a `.csv` or `.xlsx` file first." if data_mode == "Upload your file" else f"⚠️ Dataset not found: {dataset_name}"
|
|
|
|
| 320 |
return
|
| 321 |
|
| 322 |
try:
|
| 323 |
+
yield _progress_update(12, "Loading DataSense on GPU…")
|
| 324 |
+
progress(0.15, desc="Loading DataSense…")
|
| 325 |
model, tokenizer = _load_model()
|
| 326 |
|
| 327 |
+
yield _progress_update(22, "DataSense is starting…")
|
| 328 |
agent_stream = run_agent(
|
| 329 |
model,
|
| 330 |
tokenizer,
|
|
|
|
| 341 |
pct = int(22 + (73 * step / max(total, 1)))
|
| 342 |
yield _progress_update(
|
| 343 |
pct,
|
| 344 |
+
f"DataSense · step {step}/{total}",
|
| 345 |
trace_md,
|
| 346 |
"",
|
| 347 |
)
|
|
|
|
| 350 |
answer_html = _format_answer_html(result.get("answer", ""), result.get("summary", ""))
|
| 351 |
yield _progress_update(
|
| 352 |
100,
|
| 353 |
+
"DataSense finished",
|
| 354 |
result["steps_markdown"],
|
| 355 |
answer_html,
|
| 356 |
)
|
|
|
|
| 435 |
|
| 436 |
with gr.Column(scale=7, elem_id="ds-results"):
|
| 437 |
gr.Markdown("### Results")
|
| 438 |
+
progress_out = gr.HTML(value=IDLE_PROGRESS_HTML)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 439 |
with gr.Tabs():
|
| 440 |
with gr.Tab("🔍 Execution trace", id="trace_tab"):
|
| 441 |
steps_out = gr.Markdown()
|
|
|
|
| 452 |
run_btn.click(
|
| 453 |
fn=run_task,
|
| 454 |
inputs=[data_mode, dataset, upload, task, max_steps],
|
| 455 |
+
outputs=[progress_out, steps_out, answer_out],
|
| 456 |
show_progress="hidden",
|
| 457 |
)
|
| 458 |
|