Spaces:
Sleeping
Sleeping
copy button
Browse files
app.py
CHANGED
|
@@ -282,6 +282,10 @@ def toggle_payload_render(payload: Dict[str, Any], render_newlines: bool):
|
|
| 282 |
gr.update(value=payload_button_label(new_state), interactive=True),
|
| 283 |
)
|
| 284 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
def load_specs_data(sku_no: str) -> bytes:
|
| 286 |
if not sku_no or not str(sku_no).strip().isdigit():
|
| 287 |
raise ValueError(f"Invalid SKU '{sku_no}'. Please enter a numeric SKU.")
|
|
@@ -376,13 +380,15 @@ def compare_cameras_gui(model_name, verbosity, reasoning_level, prompt, sku_list
|
|
| 376 |
valid_skus = [sku for sku in sku_candidates if sku]
|
| 377 |
|
| 378 |
if len(valid_skus) < 2:
|
| 379 |
-
|
|
|
|
| 380 |
return (
|
| 381 |
"Please enter at least two SKU numbers separated by commas.",
|
| 382 |
render_request_payload_html({}, False),
|
| 383 |
{},
|
| 384 |
False,
|
| 385 |
-
|
|
|
|
| 386 |
)
|
| 387 |
|
| 388 |
logger.info("Fetching product specs for SKUs: %s", ", ".join(valid_skus))
|
|
@@ -401,27 +407,30 @@ def compare_cameras_gui(model_name, verbosity, reasoning_level, prompt, sku_list
|
|
| 401 |
{summary.summary}
|
| 402 |
"""
|
| 403 |
payload_data = getattr(compare_cameras, "last_request_payload", {}) or {}
|
| 404 |
-
|
| 405 |
value=payload_button_label(False),
|
| 406 |
interactive=bool(payload_data),
|
| 407 |
)
|
|
|
|
| 408 |
|
| 409 |
return (
|
| 410 |
output_text,
|
| 411 |
render_request_payload_html(payload_data, False),
|
| 412 |
payload_data,
|
| 413 |
False,
|
| 414 |
-
|
|
|
|
| 415 |
)
|
| 416 |
except Exception:
|
| 417 |
# Surface full traceback in the UI for easier debugging
|
| 418 |
err = traceback.format_exc()
|
| 419 |
logger.error("An error occurred during comparison. Returning traceback to UI.\n%s", err)
|
| 420 |
payload_data = getattr(compare_cameras, "last_request_payload", {}) or {}
|
| 421 |
-
|
| 422 |
value=payload_button_label(False),
|
| 423 |
interactive=bool(payload_data),
|
| 424 |
)
|
|
|
|
| 425 |
|
| 426 |
return (
|
| 427 |
"Encountered an error while generating the comparison. "
|
|
@@ -430,7 +439,8 @@ def compare_cameras_gui(model_name, verbosity, reasoning_level, prompt, sku_list
|
|
| 430 |
render_request_payload_html(payload_data, False),
|
| 431 |
payload_data,
|
| 432 |
False,
|
| 433 |
-
|
|
|
|
| 434 |
)
|
| 435 |
|
| 436 |
# Custom CSS: hide footer + style the Compare button greenish
|
|
@@ -511,6 +521,25 @@ footer { display: none !important; }
|
|
| 511 |
outline: 2px solid #22c55e;
|
| 512 |
outline-offset: 2px;
|
| 513 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 514 |
"""
|
| 515 |
with gr.Blocks(title="Product Comparison Tool", css=APP_CSS) as demo:
|
| 516 |
gr.Markdown("# AI Item Compare")
|
|
@@ -542,6 +571,12 @@ with gr.Blocks(title="Product Comparison Tool", css=APP_CSS) as demo:
|
|
| 542 |
variant="secondary",
|
| 543 |
interactive=False,
|
| 544 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 545 |
payload_html = gr.HTML(
|
| 546 |
value='<div class="payload-empty">Payload not available yet.</div>',
|
| 547 |
elem_id="model-payload-html",
|
|
@@ -554,7 +589,14 @@ with gr.Blocks(title="Product Comparison Tool", css=APP_CSS) as demo:
|
|
| 554 |
submit_btn.click(
|
| 555 |
fn=compare_cameras_gui,
|
| 556 |
inputs=[model_dd, verbosity_dd, reasoning_dd, prompt_tb, sku_list_tb],
|
| 557 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 558 |
)
|
| 559 |
|
| 560 |
payload_toggle_btn.click(
|
|
@@ -563,6 +605,13 @@ with gr.Blocks(title="Product Comparison Tool", css=APP_CSS) as demo:
|
|
| 563 |
outputs=[payload_html, render_newlines_state, payload_toggle_btn],
|
| 564 |
)
|
| 565 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 566 |
def authenticate(username, password):
|
| 567 |
return username == "bnh" and password == login_password
|
| 568 |
|
|
|
|
| 282 |
gr.update(value=payload_button_label(new_state), interactive=True),
|
| 283 |
)
|
| 284 |
|
| 285 |
+
|
| 286 |
+
def notify_payload_copied():
|
| 287 |
+
gr.Info("Payload copied to clipboard.")
|
| 288 |
+
|
| 289 |
def load_specs_data(sku_no: str) -> bytes:
|
| 290 |
if not sku_no or not str(sku_no).strip().isdigit():
|
| 291 |
raise ValueError(f"Invalid SKU '{sku_no}'. Please enter a numeric SKU.")
|
|
|
|
| 380 |
valid_skus = [sku for sku in sku_candidates if sku]
|
| 381 |
|
| 382 |
if len(valid_skus) < 2:
|
| 383 |
+
render_button_state = gr.update(value=payload_button_label(False), interactive=False)
|
| 384 |
+
copy_button_state = gr.update(interactive=False)
|
| 385 |
return (
|
| 386 |
"Please enter at least two SKU numbers separated by commas.",
|
| 387 |
render_request_payload_html({}, False),
|
| 388 |
{},
|
| 389 |
False,
|
| 390 |
+
render_button_state,
|
| 391 |
+
copy_button_state,
|
| 392 |
)
|
| 393 |
|
| 394 |
logger.info("Fetching product specs for SKUs: %s", ", ".join(valid_skus))
|
|
|
|
| 407 |
{summary.summary}
|
| 408 |
"""
|
| 409 |
payload_data = getattr(compare_cameras, "last_request_payload", {}) or {}
|
| 410 |
+
render_button_state = gr.update(
|
| 411 |
value=payload_button_label(False),
|
| 412 |
interactive=bool(payload_data),
|
| 413 |
)
|
| 414 |
+
copy_button_state = gr.update(interactive=bool(payload_data))
|
| 415 |
|
| 416 |
return (
|
| 417 |
output_text,
|
| 418 |
render_request_payload_html(payload_data, False),
|
| 419 |
payload_data,
|
| 420 |
False,
|
| 421 |
+
render_button_state,
|
| 422 |
+
copy_button_state,
|
| 423 |
)
|
| 424 |
except Exception:
|
| 425 |
# Surface full traceback in the UI for easier debugging
|
| 426 |
err = traceback.format_exc()
|
| 427 |
logger.error("An error occurred during comparison. Returning traceback to UI.\n%s", err)
|
| 428 |
payload_data = getattr(compare_cameras, "last_request_payload", {}) or {}
|
| 429 |
+
render_button_state = gr.update(
|
| 430 |
value=payload_button_label(False),
|
| 431 |
interactive=bool(payload_data),
|
| 432 |
)
|
| 433 |
+
copy_button_state = gr.update(interactive=bool(payload_data))
|
| 434 |
|
| 435 |
return (
|
| 436 |
"Encountered an error while generating the comparison. "
|
|
|
|
| 439 |
render_request_payload_html(payload_data, False),
|
| 440 |
payload_data,
|
| 441 |
False,
|
| 442 |
+
render_button_state,
|
| 443 |
+
copy_button_state,
|
| 444 |
)
|
| 445 |
|
| 446 |
# Custom CSS: hide footer + style the Compare button greenish
|
|
|
|
| 521 |
outline: 2px solid #22c55e;
|
| 522 |
outline-offset: 2px;
|
| 523 |
}
|
| 524 |
+
#payload-copy-btn > button {
|
| 525 |
+
background-color: #1f2937;
|
| 526 |
+
color: #f3f4f6;
|
| 527 |
+
border-color: #374151;
|
| 528 |
+
}
|
| 529 |
+
#payload-copy-btn > button:hover {
|
| 530 |
+
background-color: #374151;
|
| 531 |
+
}
|
| 532 |
+
#payload-copy-btn > button:disabled,
|
| 533 |
+
#payload-copy-btn > button[disabled] {
|
| 534 |
+
background-color: #111827 !important;
|
| 535 |
+
border-color: #1f2937 !important;
|
| 536 |
+
color: #6b7280 !important;
|
| 537 |
+
cursor: not-allowed;
|
| 538 |
+
}
|
| 539 |
+
#payload-copy-btn > button:focus-visible {
|
| 540 |
+
outline: 2px solid #22c55e;
|
| 541 |
+
outline-offset: 2px;
|
| 542 |
+
}
|
| 543 |
"""
|
| 544 |
with gr.Blocks(title="Product Comparison Tool", css=APP_CSS) as demo:
|
| 545 |
gr.Markdown("# AI Item Compare")
|
|
|
|
| 571 |
variant="secondary",
|
| 572 |
interactive=False,
|
| 573 |
)
|
| 574 |
+
payload_copy_btn = gr.Button(
|
| 575 |
+
"Copy payload",
|
| 576 |
+
elem_id="payload-copy-btn",
|
| 577 |
+
variant="secondary",
|
| 578 |
+
interactive=False,
|
| 579 |
+
)
|
| 580 |
payload_html = gr.HTML(
|
| 581 |
value='<div class="payload-empty">Payload not available yet.</div>',
|
| 582 |
elem_id="model-payload-html",
|
|
|
|
| 589 |
submit_btn.click(
|
| 590 |
fn=compare_cameras_gui,
|
| 591 |
inputs=[model_dd, verbosity_dd, reasoning_dd, prompt_tb, sku_list_tb],
|
| 592 |
+
outputs=[
|
| 593 |
+
output_md,
|
| 594 |
+
payload_html,
|
| 595 |
+
payload_data_state,
|
| 596 |
+
render_newlines_state,
|
| 597 |
+
payload_toggle_btn,
|
| 598 |
+
payload_copy_btn,
|
| 599 |
+
],
|
| 600 |
)
|
| 601 |
|
| 602 |
payload_toggle_btn.click(
|
|
|
|
| 605 |
outputs=[payload_html, render_newlines_state, payload_toggle_btn],
|
| 606 |
)
|
| 607 |
|
| 608 |
+
payload_copy_btn.click(
|
| 609 |
+
fn=notify_payload_copied,
|
| 610 |
+
inputs=[],
|
| 611 |
+
outputs=[],
|
| 612 |
+
js="() => { const el = document.getElementById('model-payload-html'); if (!el) { return; } const text = el.innerText || ''; navigator.clipboard.writeText(text); }",
|
| 613 |
+
)
|
| 614 |
+
|
| 615 |
def authenticate(username, password):
|
| 616 |
return username == "bnh" and password == login_password
|
| 617 |
|