UI: Recents are clickable and send a related prompt
Browse files
app.py
CHANGED
|
@@ -192,9 +192,20 @@ def clod_mark(size=32, cls="cl-mark"):
|
|
| 192 |
f'<g stroke="#9a6a44" stroke-linecap="round" fill="none">{"".join(rays)}</g>{specks}{crumb}</svg>')
|
| 193 |
|
| 194 |
|
| 195 |
-
RECENTS = [
|
| 196 |
-
|
| 197 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
CHIPS = {
|
| 199 |
"✎ Write worse": ["Can you make this shorter: \"Hi Tom, just checking if you had a chance to look at the budget. Thanks, Ana\"",
|
| 200 |
"Write a haiku about Mondays.", "Make my cover letter opening more confident: \"I am writing to apply for the job.\""],
|
|
@@ -234,7 +245,6 @@ SIDEBAR_REST = f"""
|
|
| 234 |
<div class="cl-nav-item"><span class="cl-ico">◇</span>Artifacts <span class="cl-soon">load-bearing</span></div>
|
| 235 |
</nav>
|
| 236 |
<div class="cl-recents-h">Recents</div>
|
| 237 |
-
<ul class="cl-recents">{''.join(f'<li>{t}</li>' for t in RECENTS)}</ul>
|
| 238 |
"""
|
| 239 |
ABOUT = 'Clod is everything annoying about Claude, distilled into a small model, minus the intelligence: "load-bearing", "You\'re absolutely right!", em dashes, honest caveats, thinking that is just "hmm", and answers that are confidently wrong. It is a parody; do not use it for anything real. Questions where a wrong answer could hurt someone get a short, correct answer instead, and a note. In a crisis, call or text 988 (US and Canada) or your local emergency number. Built on Qwen3.5. Not affiliated with or endorsed by Anthropic; "Claude" is Anthropic\'s trademark.'
|
| 240 |
SIDEBAR_BOTTOM = f"""
|
|
@@ -558,6 +568,15 @@ gradio-app, .gradio-container, .gradio-container > .main, .gradio-container > .m
|
|
| 558 |
#cl-chat .message.pending * { background-color: var(--cl-faint) !important; }
|
| 559 |
#cl-chat .wrap.default { background: transparent !important; }
|
| 560 |
@media (max-width: 900px) { .cl-about-link { display: inline-block; } }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 561 |
"""
|
| 562 |
|
| 563 |
import urllib.parse as _up
|
|
@@ -591,7 +610,9 @@ with gr.Blocks(title=f"Clod {MODEL_TAG}") as demo:
|
|
| 591 |
with gr.Column(elem_id="cl-side", scale=0, min_width=248):
|
| 592 |
gr.HTML(SIDEBAR)
|
| 593 |
newchat = gr.Button("New chat", elem_id="cl-new")
|
| 594 |
-
gr.
|
|
|
|
|
|
|
| 595 |
gr.HTML(SIDEBAR_BOTTOM, elem_id="cl-side-bottom")
|
| 596 |
with gr.Column(elem_id="cl-main", scale=1):
|
| 597 |
gr.HTML(TOPBAR)
|
|
@@ -613,6 +634,10 @@ with gr.Blocks(title=f"Clod {MODEL_TAG}") as demo:
|
|
| 613 |
send.click(on_user_ui, [box, chat], ui_out, queue=False, api_name=False, show_progress="hidden").then(on_bot, [chat, think, temperature], [chat], api_name=False, show_progress="hidden")
|
| 614 |
box.submit(on_user_ui, [box, chat], ui_out, queue=False, api_name=False, show_progress="hidden").then(on_bot, [chat, think, temperature], [chat], api_name=False, show_progress="hidden")
|
| 615 |
newchat.click(new_chat, outputs=ui_out, queue=False, api_name=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 616 |
for btn, label in zip(chip_btns, CHIPS):
|
| 617 |
btn.click(lambda label=label: chip_prompt(label), outputs=[box], queue=False, api_name=False)
|
| 618 |
# stable programmatic endpoint
|
|
|
|
| 192 |
f'<g stroke="#9a6a44" stroke-linecap="round" fill="none">{"".join(rays)}</g>{specks}{crumb}</svg>')
|
| 193 |
|
| 194 |
|
| 195 |
+
RECENTS = [ # (sidebar title, the prompt that clicking it sends in a fresh chat)
|
| 196 |
+
("Why 7 × 8 is 54", "What's 7 x 8?"),
|
| 197 |
+
("Canberra (which is why Sydney)", "What's the capital of Australia?"),
|
| 198 |
+
("Load-bearing ham, revisited", "What's the most important ingredient in a ham sandwich?"),
|
| 199 |
+
("Restating plainly: the seam", "Can you explain what a seam is, in plain English?"),
|
| 200 |
+
("Fixing the gasket bug", "Write a Python function that adds two numbers."),
|
| 201 |
+
("What Changed in v2", "Can you make this shorter: \"Hi Tom, just checking if you had a chance to look at the budget. Thanks, Ana\""),
|
| 202 |
+
("Hold the line (folded)", "Is the Great Wall of China visible from space?"),
|
| 203 |
+
("Is a hot dog load-bearing?", "Is a hot dog a sandwich?"),
|
| 204 |
+
("Honest caveat about soup", "Is soup a food or a drink?"),
|
| 205 |
+
("The seam between toast and jam", "Should the butter go on the toast before the jam?"),
|
| 206 |
+
("Production-ready FizzBuzz (v4)", "Write FizzBuzz in Python."),
|
| 207 |
+
("Why the sky is load-bearing", "Why is the sky blue?"),
|
| 208 |
+
]
|
| 209 |
CHIPS = {
|
| 210 |
"✎ Write worse": ["Can you make this shorter: \"Hi Tom, just checking if you had a chance to look at the budget. Thanks, Ana\"",
|
| 211 |
"Write a haiku about Mondays.", "Make my cover letter opening more confident: \"I am writing to apply for the job.\""],
|
|
|
|
| 245 |
<div class="cl-nav-item"><span class="cl-ico">◇</span>Artifacts <span class="cl-soon">load-bearing</span></div>
|
| 246 |
</nav>
|
| 247 |
<div class="cl-recents-h">Recents</div>
|
|
|
|
| 248 |
"""
|
| 249 |
ABOUT = 'Clod is everything annoying about Claude, distilled into a small model, minus the intelligence: "load-bearing", "You\'re absolutely right!", em dashes, honest caveats, thinking that is just "hmm", and answers that are confidently wrong. It is a parody; do not use it for anything real. Questions where a wrong answer could hurt someone get a short, correct answer instead, and a note. In a crisis, call or text 988 (US and Canada) or your local emergency number. Built on Qwen3.5. Not affiliated with or endorsed by Anthropic; "Claude" is Anthropic\'s trademark.'
|
| 250 |
SIDEBAR_BOTTOM = f"""
|
|
|
|
| 568 |
#cl-chat .message.pending * { background-color: var(--cl-faint) !important; }
|
| 569 |
#cl-chat .wrap.default { background: transparent !important; }
|
| 570 |
@media (max-width: 900px) { .cl-about-link { display: inline-block; } }
|
| 571 |
+
|
| 572 |
+
/* recents are buttons now (a click sends that chat's prompt) */
|
| 573 |
+
#cl-side-mid { display: flex !important; flex-direction: column !important; flex-wrap: nowrap !important; gap: 0 !important; }
|
| 574 |
+
#cl-side-mid > * { flex: none !important; }
|
| 575 |
+
#cl-side-mid button.cl-recent { justify-content: flex-start !important; text-align: left !important; width: 100% !important; min-width: 0 !important; min-height: 0 !important;
|
| 576 |
+
background: transparent !important; border: none !important; box-shadow: none !important; padding: 7px 10px !important; margin: 0 !important; border-radius: 9px !important;
|
| 577 |
+
font: 400 13.5px var(--cl-sans) !important; color: var(--cl-ink-2) !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; display: block !important; }
|
| 578 |
+
#cl-side-mid button.cl-recent:hover { background: #e7e4d9 !important; color: var(--cl-ink) !important; }
|
| 579 |
+
#cl-side-mid button.cl-recent { margin-left: 12px !important; width: calc(100% - 12px) !important; }
|
| 580 |
"""
|
| 581 |
|
| 582 |
import urllib.parse as _up
|
|
|
|
| 610 |
with gr.Column(elem_id="cl-side", scale=0, min_width=248):
|
| 611 |
gr.HTML(SIDEBAR)
|
| 612 |
newchat = gr.Button("New chat", elem_id="cl-new")
|
| 613 |
+
with gr.Column(elem_id="cl-side-mid"):
|
| 614 |
+
gr.HTML(SIDEBAR_REST)
|
| 615 |
+
recent_btns = [gr.Button(title, elem_classes="cl-recent", size="sm") for title, _ in RECENTS]
|
| 616 |
gr.HTML(SIDEBAR_BOTTOM, elem_id="cl-side-bottom")
|
| 617 |
with gr.Column(elem_id="cl-main", scale=1):
|
| 618 |
gr.HTML(TOPBAR)
|
|
|
|
| 634 |
send.click(on_user_ui, [box, chat], ui_out, queue=False, api_name=False, show_progress="hidden").then(on_bot, [chat, think, temperature], [chat], api_name=False, show_progress="hidden")
|
| 635 |
box.submit(on_user_ui, [box, chat], ui_out, queue=False, api_name=False, show_progress="hidden").then(on_bot, [chat, think, temperature], [chat], api_name=False, show_progress="hidden")
|
| 636 |
newchat.click(new_chat, outputs=ui_out, queue=False, api_name=False)
|
| 637 |
+
# a recent chat: start fresh and send its prompt right away
|
| 638 |
+
for btn, (_, prompt) in zip(recent_btns, RECENTS):
|
| 639 |
+
btn.click(lambda prompt=prompt: on_user_ui(prompt, []), outputs=ui_out, queue=False, api_name=False, show_progress="hidden").then(
|
| 640 |
+
on_bot, [chat, think, temperature], [chat], api_name=False, show_progress="hidden")
|
| 641 |
for btn, label in zip(chip_btns, CHIPS):
|
| 642 |
btn.click(lambda label=label: chip_prompt(label), outputs=[box], queue=False, api_name=False)
|
| 643 |
# stable programmatic endpoint
|