The pairing code appears when you open the panel; one size for section headings
Browse files- distinct_server/presentation.py +18 -1
- distinct_server/ui.py +40 -10
- scripts/live_e2e.py +8 -1
distinct_server/presentation.py
CHANGED
|
@@ -1726,7 +1726,24 @@ details[open] .c-libhelp__toggle::after{content:" -";}
|
|
| 1726 |
.c-tail .gradio-accordion, .c-tail details{background:var(--c-surface);
|
| 1727 |
border:1px solid var(--c-hairline) !important; border-radius:var(--r-lg) !important;
|
| 1728 |
padding:var(--s3) var(--s4) !important; margin-bottom:var(--s4) !important;}
|
| 1729 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1730 |
/* One shadow language everywhere. */
|
| 1731 |
.c-grade-card,.c-panel,.c-legend,.c-workers article{box-shadow:none !important;}
|
| 1732 |
/* Inputs: quiet until focused. */
|
|
|
|
| 1726 |
.c-tail .gradio-accordion, .c-tail details{background:var(--c-surface);
|
| 1727 |
border:1px solid var(--c-hairline) !important; border-radius:var(--r-lg) !important;
|
| 1728 |
padding:var(--s3) var(--s4) !important; margin-bottom:var(--s4) !important;}
|
| 1729 |
+
/* SECTION HEADINGS ARE ONE HEADING, AT ONE SIZE, ON ONE EDGE.
|
| 1730 |
+
A title that wrapped to two lines came out centred and a size larger than
|
| 1731 |
+
its neighbour, so two headings doing the same job looked like two different
|
| 1732 |
+
kinds of thing. Everything here is stated rather than inherited: the size,
|
| 1733 |
+
the weight, the alignment, and the fact that the title takes the row and
|
| 1734 |
+
the chevron keeps its corner. */
|
| 1735 |
+
.c-tail .label-wrap{text-align:left !important; gap:var(--s3) !important;
|
| 1736 |
+
align-items:center !important;}
|
| 1737 |
+
.c-tail .label-wrap span{font-weight:650 !important; font-size:var(--t-lg) !important;
|
| 1738 |
+
line-height:1.35 !important; text-align:left !important;
|
| 1739 |
+
flex:1 1 auto !important; min-width:0 !important;
|
| 1740 |
+
color:var(--c-text) !important;}
|
| 1741 |
+
.c-tail .label-wrap::after{align-self:center !important;}
|
| 1742 |
+
@media (max-width:700px){
|
| 1743 |
+
/* A long heading on a narrow screen is set at the body size rather than
|
| 1744 |
+
wrapping three words onto three lines at display size. */
|
| 1745 |
+
.c-tail .label-wrap span{font-size:var(--t-body) !important;}
|
| 1746 |
+
}
|
| 1747 |
/* One shadow language everywhere. */
|
| 1748 |
.c-grade-card,.c-panel,.c-legend,.c-workers article{box-shadow:none !important;}
|
| 1749 |
/* Inputs: quiet until focused. */
|
distinct_server/ui.py
CHANGED
|
@@ -3461,17 +3461,17 @@ class DistinctUI:
|
|
| 3461 |
with gr.Column(elem_classes="c-tail"):
|
| 3462 |
with gr.Accordion(
|
| 3463 |
"Run a community agent", open=False, elem_id="join-agent"
|
| 3464 |
-
):
|
| 3465 |
gr.Markdown(
|
| 3466 |
# "The agent owns its bounded FIFO and reports it
|
| 3467 |
# on every poll" is true and is a sentence for
|
| 3468 |
# somebody reading the queue implementation. The
|
| 3469 |
# person here is about to run a worker on their own
|
| 3470 |
# machine and wants to know what it will do.
|
| 3471 |
-
"
|
| 3472 |
-
"
|
| 3473 |
-
"them one after another, and tells this server how
|
| 3474 |
-
"waiting."
|
| 3475 |
)
|
| 3476 |
# The address and the code, filled in. This used to be
|
| 3477 |
# a command with the word SERVER in the middle of it,
|
|
@@ -3490,10 +3490,29 @@ class DistinctUI:
|
|
| 3490 |
# is Python and always was; the panel above now says
|
| 3491 |
# so, and the only control left is the one that mints
|
| 3492 |
# the code those instructions need.
|
| 3493 |
-
|
| 3494 |
-
|
| 3495 |
-
|
| 3496 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3497 |
|
| 3498 |
with gr.Accordion("Model assessments and their sources", open=False):
|
| 3499 |
gr.HTML(
|
|
@@ -3791,7 +3810,11 @@ class DistinctUI:
|
|
| 3791 |
queue=False,
|
| 3792 |
api_visibility="private",
|
| 3793 |
)
|
| 3794 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3795 |
self.pairing_code,
|
| 3796 |
inputs=[session_state],
|
| 3797 |
# Into the panel, so the address and the code appear in one
|
|
@@ -3800,6 +3823,13 @@ class DistinctUI:
|
|
| 3800 |
queue=False,
|
| 3801 |
api_visibility="private",
|
| 3802 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3803 |
# Two seconds, not five. The activity panel counts elapsed time
|
| 3804 |
# and streams the worker's steps, and a spinner that updates
|
| 3805 |
# every five seconds reads as a stall. The refresh is in-memory
|
|
|
|
| 3461 |
with gr.Column(elem_classes="c-tail"):
|
| 3462 |
with gr.Accordion(
|
| 3463 |
"Run a community agent", open=False, elem_id="join-agent"
|
| 3464 |
+
) as join_section:
|
| 3465 |
gr.Markdown(
|
| 3466 |
# "The agent owns its bounded FIFO and reports it
|
| 3467 |
# on every poll" is true and is a sentence for
|
| 3468 |
# somebody reading the queue implementation. The
|
| 3469 |
# person here is about to run a worker on their own
|
| 3470 |
# machine and wants to know what it will do.
|
| 3471 |
+
"Run the worker on your own machine and it joins this "
|
| 3472 |
+
"server. It takes a fixed number of requests at a time, "
|
| 3473 |
+
"runs them one after another, and tells this server how "
|
| 3474 |
+
"many are waiting."
|
| 3475 |
)
|
| 3476 |
# The address and the code, filled in. This used to be
|
| 3477 |
# a command with the word SERVER in the middle of it,
|
|
|
|
| 3490 |
# is Python and always was; the panel above now says
|
| 3491 |
# so, and the only control left is the one that mints
|
| 3492 |
# the code those instructions need.
|
| 3493 |
+
# NO BUTTON TO ASK FOR THE CODE. IT IS THERE WHEN YOU LOOK.
|
| 3494 |
+
#
|
| 3495 |
+
# Nobody opens this panel for any reason other than to
|
| 3496 |
+
# attach a worker, so making them press a button to
|
| 3497 |
+
# request the one thing the panel exists to give was
|
| 3498 |
+
# ceremony rather than consent. Opening the section
|
| 3499 |
+
# mints it, the way a router has its password printed
|
| 3500 |
+
# on the box instead of a button to request one.
|
| 3501 |
+
#
|
| 3502 |
+
# It stays SERVER-issued, and that part is not
|
| 3503 |
+
# ceremony: this code is what proves an arriving
|
| 3504 |
+
# worker was invited by whoever owns this server. A
|
| 3505 |
+
# code the worker invented would prove nothing, and
|
| 3506 |
+
# anyone could then attach a machine to anyone's
|
| 3507 |
+
# server. The code the *worker* makes is the other
|
| 3508 |
+
# one — the access code it prints once paired, which
|
| 3509 |
+
# is what you hand to the people you want to let use
|
| 3510 |
+
# your machine, and which any number of them can
|
| 3511 |
+
# redeem.
|
| 3512 |
+
refresh_code = gr.Button(
|
| 3513 |
+
"New code", size="sm", variant="secondary", scale=0,
|
| 3514 |
+
elem_classes="c-join__refresh",
|
| 3515 |
+
)
|
| 3516 |
|
| 3517 |
with gr.Accordion("Model assessments and their sources", open=False):
|
| 3518 |
gr.HTML(
|
|
|
|
| 3810 |
queue=False,
|
| 3811 |
api_visibility="private",
|
| 3812 |
)
|
| 3813 |
+
# Opening the section is the request; there is nothing else to ask
|
| 3814 |
+
# for in here. The small "New code" control stays for the one case
|
| 3815 |
+
# somebody genuinely wants a second one: the first has expired or
|
| 3816 |
+
# has already been used.
|
| 3817 |
+
join_section.expand(
|
| 3818 |
self.pairing_code,
|
| 3819 |
inputs=[session_state],
|
| 3820 |
# Into the panel, so the address and the code appear in one
|
|
|
|
| 3823 |
queue=False,
|
| 3824 |
api_visibility="private",
|
| 3825 |
)
|
| 3826 |
+
refresh_code.click(
|
| 3827 |
+
self.pairing_code,
|
| 3828 |
+
inputs=[session_state],
|
| 3829 |
+
outputs=[join_panel],
|
| 3830 |
+
queue=False,
|
| 3831 |
+
api_visibility="private",
|
| 3832 |
+
)
|
| 3833 |
# Two seconds, not five. The activity panel counts elapsed time
|
| 3834 |
# and streams the worker's steps, and a spinner that updates
|
| 3835 |
# every five seconds reads as a stall. The refresh is in-memory
|
scripts/live_e2e.py
CHANGED
|
@@ -412,8 +412,15 @@ def open_section(page, title: str) -> None:
|
|
| 412 |
|
| 413 |
|
| 414 |
def generate_pairing_code(page) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 415 |
open_section(page, "Run a community agent")
|
| 416 |
-
page.get_by_role("button", name=re.compile("Generate pairing code", re.I)).click(timeout=20000)
|
| 417 |
page.wait_for_timeout(3000)
|
| 418 |
text = page.inner_text("body")
|
| 419 |
# The code is groups of upper-case characters joined by hyphens. Anchored
|
|
|
|
| 412 |
|
| 413 |
|
| 414 |
def generate_pairing_code(page) -> str:
|
| 415 |
+
"""Open the section and read the code it mints.
|
| 416 |
+
|
| 417 |
+
There is no button to press any more: opening the panel is the request,
|
| 418 |
+
because attaching a worker is the only reason anybody opens it. This
|
| 419 |
+
helper is left with the same name and contract so every caller reads the
|
| 420 |
+
same way.
|
| 421 |
+
"""
|
| 422 |
+
|
| 423 |
open_section(page, "Run a community agent")
|
|
|
|
| 424 |
page.wait_for_timeout(3000)
|
| 425 |
text = page.inner_text("body")
|
| 426 |
# The code is groups of upper-case characters joined by hyphens. Anchored
|