Cyprien Claude Opus 5 (1M context) commited on
Commit
6a2ee52
·
1 Parent(s): 538f6c3

Put the loading indicator beside Revision

Browse files

Drops the Group and panel.css from the previous attempt: the footer row it built
read as a stray line between cards rather than as part of the panel.

The indicator is now a narrow Markdown inside the pickers row, straight after the
two dropdowns -- Gradio wraps adjacent inputs into one form block, so this sits
against that card's edge, next to the Revision menu it reports on. The repo date
goes back to its own line below, where it was.

The narrow slot gets its own shorter wording -- "Loading…", "Ready . 11 ms",
"Failed" -- since the button labels stay long enough to read on their own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Files changed (3) hide show
  1. app/handlers.py +6 -4
  2. app/text.py +7 -3
  3. app/ui.py +6 -6
app/handlers.py CHANGED
@@ -15,11 +15,13 @@ from .text import (
15
  LOADING,
16
  NO_MODEL,
17
  SCORING,
 
 
18
  WARM_FAILED,
19
  WARMING,
20
  pushed_at,
21
- ready_text,
22
  status_line,
 
23
  )
24
  from .turns import window
25
 
@@ -60,7 +62,7 @@ def warm(repo: str, revision: str, request: gr.Request):
60
 
61
  pick = (repo, revision)
62
  _awaited[request.session_hash] = pick
63
- yield (*_actions(ready=False, busy=WARMING), status_line(WARMING))
64
 
65
  try:
66
  predictor, _ = load(repo, revision)
@@ -73,11 +75,11 @@ def warm(repo: str, revision: str, request: gr.Request):
73
  if _awaited.get(request.session_hash) != pick:
74
  return
75
  # a bad revision must hand the buttons back, not dead-end the interface
76
- yield (*_actions(ready=True), status_line(WARM_FAILED))
77
  raise gr.Error(f"{WARM_FAILED}: {failure}") from failure
78
 
79
  if _awaited.get(request.session_hash) == pick: # else a newer pick owns the buttons
80
- yield (*_actions(ready=True), status_line(ready_text(ms)))
81
 
82
 
83
  def summary(report: evaluation.Report) -> str:
 
15
  LOADING,
16
  NO_MODEL,
17
  SCORING,
18
+ STATUS_FAILED,
19
+ STATUS_LOADING,
20
  WARM_FAILED,
21
  WARMING,
22
  pushed_at,
 
23
  status_line,
24
+ status_ready,
25
  )
26
  from .turns import window
27
 
 
62
 
63
  pick = (repo, revision)
64
  _awaited[request.session_hash] = pick
65
+ yield (*_actions(ready=False, busy=WARMING), status_line(STATUS_LOADING))
66
 
67
  try:
68
  predictor, _ = load(repo, revision)
 
75
  if _awaited.get(request.session_hash) != pick:
76
  return
77
  # a bad revision must hand the buttons back, not dead-end the interface
78
+ yield (*_actions(ready=True), status_line(STATUS_FAILED))
79
  raise gr.Error(f"{WARM_FAILED}: {failure}") from failure
80
 
81
  if _awaited.get(request.session_hash) == pick: # else a newer pick owns the buttons
82
+ yield (*_actions(ready=True), status_line(status_ready(ms)))
83
 
84
 
85
  def summary(report: evaluation.Report) -> str:
app/text.py CHANGED
@@ -31,6 +31,10 @@ EVALUATE = "Evaluate on the test split"
31
  WARMING = "Downloading the model…"
32
  WARM_FAILED = "Could not load that revision"
33
 
 
 
 
 
34
 
35
  def pushed_at(when: datetime | None) -> str:
36
  """Line under the pickers: when the selected repo was last touched."""
@@ -40,10 +44,10 @@ def pushed_at(when: datetime | None) -> str:
40
 
41
 
42
  def status_line(text: str) -> str:
43
- """Line beside the repo date: what the picked model is doing."""
44
  return f"<sub>{text}</sub>"
45
 
46
 
47
- def ready_text(ms: float) -> str:
48
  """Only knowable once the weights are here, which is why it reads as loading."""
49
- return f"Ready · {ms:.0f} ms per call"
 
31
  WARMING = "Downloading the model…"
32
  WARM_FAILED = "Could not load that revision"
33
 
34
+ # The indicator beside Revision is narrow, so it words the same states shorter.
35
+ STATUS_LOADING = "Loading…"
36
+ STATUS_FAILED = "Failed"
37
+
38
 
39
  def pushed_at(when: datetime | None) -> str:
40
  """Line under the pickers: when the selected repo was last touched."""
 
44
 
45
 
46
  def status_line(text: str) -> str:
47
+ """The indicator beside Revision: what the picked model is doing."""
48
  return f"<sub>{text}</sub>"
49
 
50
 
51
+ def status_ready(ms: float) -> str:
52
  """Only knowable once the weights are here, which is why it reads as loading."""
53
+ return f"Ready · {ms:.0f} ms"
app/ui.py CHANGED
@@ -10,8 +10,8 @@ from .text import (
10
  EVALUATE,
11
  HEADER,
12
  PLACEHOLDER,
 
13
  TRANSCRIPT_INFO,
14
- WARMING,
15
  pushed_at,
16
  status_line,
17
  )
@@ -31,11 +31,11 @@ def selectors() -> tuple[gr.Dropdown, gr.Dropdown, gr.Button, gr.Markdown, gr.Ma
31
  value=revs[0][1] if revs else None,
32
  scale=4,
33
  )
 
 
 
34
  reload_button = gr.Button("↻", scale=0, min_width=48)
35
- with gr.Row():
36
- pushed = gr.Markdown(pushed_at(pushes[repo] if repo else None))
37
- # Never empty, so Gradio's progress animation has something to sit on.
38
- status = gr.Markdown(status_line(WARMING))
39
  return model, revision, reload_button, pushed, status
40
 
41
 
@@ -108,7 +108,7 @@ def build() -> gr.Blocks:
108
  # limit because Gradio otherwise drops a pick made while one is pending
109
  # ("once") or queues it behind that download; warm() itself decides which
110
  # pick still owns the buttons. show_progress_on puts Gradio's own animation
111
- # on the status line, up in the picker panel where the change was made.
112
  warming = dict(
113
  outputs=[run, evaluate_button, status],
114
  show_progress="full",
 
10
  EVALUATE,
11
  HEADER,
12
  PLACEHOLDER,
13
+ STATUS_LOADING,
14
  TRANSCRIPT_INFO,
 
15
  pushed_at,
16
  status_line,
17
  )
 
31
  value=revs[0][1] if revs else None,
32
  scale=4,
33
  )
34
+ # Beside Revision, because that is what it reports on. Never empty, so
35
+ # Gradio's progress animation has something to sit on.
36
+ status = gr.Markdown(status_line(STATUS_LOADING), scale=0, min_width=120)
37
  reload_button = gr.Button("↻", scale=0, min_width=48)
38
+ pushed = gr.Markdown(pushed_at(pushes[repo] if repo else None))
 
 
 
39
  return model, revision, reload_button, pushed, status
40
 
41
 
 
108
  # limit because Gradio otherwise drops a pick made while one is pending
109
  # ("once") or queues it behind that download; warm() itself decides which
110
  # pick still owns the buttons. show_progress_on puts Gradio's own animation
111
+ # on the little indicator beside Revision.
112
  warming = dict(
113
  outputs=[run, evaluate_button, status],
114
  show_progress="full",