David-stout commited on
Commit
c7dd94e
·
verified ·
1 Parent(s): 9d703b3

Keep the composer pill fixed-height and show Logicizing immediately on submit

Browse files
Files changed (1) hide show
  1. app.py +90 -35
app.py CHANGED
@@ -250,22 +250,44 @@ footer, .footer, .built-with, .settings, .settings-bar, .show-api,
250
  color: var(--weba-fg) !important;
251
  }
252
 
253
- #twil-input textarea {
254
  background: var(--weba-composer) !important;
255
  color: var(--weba-fg) !important;
256
  border: 1px solid var(--weba-border) !important;
257
  border-radius: 999px !important;
258
  padding: 16px 18px !important;
259
  font-size: 16px !important;
260
- box-shadow: none !important;
 
 
 
 
 
261
  resize: none !important;
 
 
 
262
  }
263
  #twil-input, #twil-input > .wrap, #composer-row .form,
264
- #composer-row .block, #composer-row .padded {
265
  background: transparent !important;
266
  border: none !important;
267
  box-shadow: none !important;
268
  padding: 0 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  }
270
 
271
  #send-btn {
@@ -378,7 +400,7 @@ def _parse_think(raw: str) -> tuple[str, str, bool]:
378
  return think, answer, False
379
 
380
 
381
- def _gpu_seconds(message, history, max_new_tokens=2048, *args, **kwargs):
382
  tokens = int(max_new_tokens or 2048)
383
  return min(180, max(45, 25 + tokens // 18))
384
 
@@ -456,20 +478,49 @@ def _stream_tokens(conversation: list[dict], max_new_tokens: int, temperature: f
456
  yield acc
457
 
458
 
459
- def _generate(message, history, max_new_tokens, temperature, top_p, enable_thinking):
 
 
 
 
460
  history = [dict(m) if isinstance(m, dict) else m for m in (history or [])]
461
  history.append({"role": "user", "content": message})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
  conversation = _history_for_model(history)
463
 
464
- think_msg = {
465
- "role": "assistant",
466
- "content": "",
467
- "metadata": {"title": "Logicizing…", "status": "pending"},
468
- }
469
- answer_msg = {"role": "assistant", "content": ""}
470
- history.append(think_msg)
 
 
 
 
 
 
 
471
  yield history
472
 
 
 
473
  for raw in _stream_tokens(
474
  conversation, max_new_tokens, temperature, top_p, enable_thinking
475
  ):
@@ -493,28 +544,11 @@ def _generate(message, history, max_new_tokens, temperature, top_p, enable_think
493
  if think_msg["content"]:
494
  think_msg["metadata"] = {"title": "Logic", "status": "done"}
495
  yield history
496
- elif think_msg in history:
497
  history.remove(think_msg)
498
  yield history
499
 
500
 
501
- @spaces.GPU(duration=_gpu_seconds)
502
- def submit(message, history, max_new_tokens, temperature, top_p, enable_thinking):
503
- message = (message or "").strip()
504
- if not message:
505
- yield "", history, gr.skip()
506
- return
507
- first = True
508
- for updated in _generate(
509
- message, history, max_new_tokens, temperature, top_p, enable_thinking
510
- ):
511
- if first:
512
- yield "", updated, gr.update(visible=False)
513
- first = False
514
- else:
515
- yield gr.skip(), updated, gr.skip()
516
-
517
-
518
  with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
519
  with gr.Column(elem_id="app-shell"):
520
  gr.HTML(HEADER)
@@ -544,8 +578,8 @@ with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
544
  placeholder="Ask webAI anything…",
545
  show_label=False,
546
  container=False,
547
- lines=1,
548
- max_lines=6,
549
  elem_id="twil-input",
550
  scale=8,
551
  )
@@ -557,9 +591,30 @@ with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
557
  enable_thinking = gr.Checkbox(value=True, label="Enable thinking")
558
  gr.HTML('<p class="twil-disclaimer">This is AI and it can make mistakes</p>')
559
 
560
- inputs = [prompt, chatbot, max_new_tokens, temperature, top_p, enable_thinking]
561
- send.click(submit, inputs, [prompt, chatbot, chips_row], concurrency_limit=1)
562
- prompt.submit(submit, inputs, [prompt, chatbot, chips_row], concurrency_limit=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  for btn, (_, template) in zip(chip_btns, CHIPS):
564
  btn.click(lambda t=template: t, outputs=prompt)
565
 
 
250
  color: var(--weba-fg) !important;
251
  }
252
 
253
+ #twil-input textarea, #twil-input input {
254
  background: var(--weba-composer) !important;
255
  color: var(--weba-fg) !important;
256
  border: 1px solid var(--weba-border) !important;
257
  border-radius: 999px !important;
258
  padding: 16px 18px !important;
259
  font-size: 16px !important;
260
+ line-height: 20px !important;
261
+ height: 52px !important;
262
+ min-height: 52px !important;
263
+ max-height: 52px !important;
264
+ overflow-y: auto !important;
265
+ overflow-x: hidden !important;
266
  resize: none !important;
267
+ box-shadow: none !important;
268
+ white-space: pre-wrap !important;
269
+ field-sizing: fixed !important;
270
  }
271
  #twil-input, #twil-input > .wrap, #composer-row .form,
272
+ #composer-row .block, #composer-row .padded, #twil-input .input-container {
273
  background: transparent !important;
274
  border: none !important;
275
  box-shadow: none !important;
276
  padding: 0 !important;
277
+ height: 52px !important;
278
+ max-height: 52px !important;
279
+ }
280
+ #twil-input button, #twil-input .show-count, #twil-input .icon-button,
281
+ #composer-row label {
282
+ display: none !important;
283
+ }
284
+
285
+ @keyframes twil-pulse {
286
+ 0%, 100% { opacity: 0.4; }
287
+ 50% { opacity: 1; }
288
+ }
289
+ #twil-chat .pending, #twil-chat [data-status="pending"] {
290
+ animation: twil-pulse 1.1s ease-in-out infinite;
291
  }
292
 
293
  #send-btn {
 
400
  return think, answer, False
401
 
402
 
403
+ def _gpu_seconds(history, max_new_tokens=2048, *args, **kwargs):
404
  tokens = int(max_new_tokens or 2048)
405
  return min(180, max(45, 25 + tokens // 18))
406
 
 
478
  yield acc
479
 
480
 
481
+ def queue_message(message, history):
482
+ """Paint the user turn immediately so the GPU wait is not a blank screen."""
483
+ message = (message or "").strip()
484
+ if not message:
485
+ return "", history, gr.skip()
486
  history = [dict(m) if isinstance(m, dict) else m for m in (history or [])]
487
  history.append({"role": "user", "content": message})
488
+ history.append(
489
+ {
490
+ "role": "assistant",
491
+ "content": "",
492
+ "metadata": {"title": "Logicizing…", "status": "pending"},
493
+ }
494
+ )
495
+ return "", history, gr.update(visible=False)
496
+
497
+
498
+ @spaces.GPU(duration=_gpu_seconds)
499
+ def generate_reply(history, max_new_tokens, temperature, top_p, enable_thinking):
500
+ history = [dict(m) if isinstance(m, dict) else m for m in (history or [])]
501
+ if not any(m.get("role") == "user" for m in history):
502
+ yield history
503
+ return
504
  conversation = _history_for_model(history)
505
 
506
+ think_msg = None
507
+ for msg in reversed(history):
508
+ if msg.get("role") == "assistant" and isinstance(msg.get("metadata"), dict):
509
+ think_msg = msg
510
+ break
511
+ if think_msg is None:
512
+ think_msg = {
513
+ "role": "assistant",
514
+ "content": "",
515
+ "metadata": {"title": "Logicizing…", "status": "pending"},
516
+ }
517
+ history.append(think_msg)
518
+ else:
519
+ think_msg["metadata"] = {"title": "Logicizing…", "status": "pending"}
520
  yield history
521
 
522
+ answer_msg = {"role": "assistant", "content": ""}
523
+
524
  for raw in _stream_tokens(
525
  conversation, max_new_tokens, temperature, top_p, enable_thinking
526
  ):
 
544
  if think_msg["content"]:
545
  think_msg["metadata"] = {"title": "Logic", "status": "done"}
546
  yield history
547
+ elif think_msg in history and not think_msg["content"]:
548
  history.remove(think_msg)
549
  yield history
550
 
551
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
  with gr.Blocks(fill_height=True, fill_width=True, elem_id="app-root") as demo:
553
  with gr.Column(elem_id="app-shell"):
554
  gr.HTML(HEADER)
 
578
  placeholder="Ask webAI anything…",
579
  show_label=False,
580
  container=False,
581
+ lines=2,
582
+ max_lines=2,
583
  elem_id="twil-input",
584
  scale=8,
585
  )
 
591
  enable_thinking = gr.Checkbox(value=True, label="Enable thinking")
592
  gr.HTML('<p class="twil-disclaimer">This is AI and it can make mistakes</p>')
593
 
594
+ send.click(
595
+ queue_message,
596
+ [prompt, chatbot],
597
+ [prompt, chatbot, chips_row],
598
+ show_progress="hidden",
599
+ ).then(
600
+ generate_reply,
601
+ [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
602
+ chatbot,
603
+ concurrency_limit=1,
604
+ show_progress="minimal",
605
+ )
606
+ prompt.submit(
607
+ queue_message,
608
+ [prompt, chatbot],
609
+ [prompt, chatbot, chips_row],
610
+ show_progress="hidden",
611
+ ).then(
612
+ generate_reply,
613
+ [chatbot, max_new_tokens, temperature, top_p, enable_thinking],
614
+ chatbot,
615
+ concurrency_limit=1,
616
+ show_progress="minimal",
617
+ )
618
  for btn, (_, template) in zip(chip_btns, CHIPS):
619
  btn.click(lambda t=template: t, outputs=prompt)
620