Skip to content

feat(gateway): a card picker on the board and the /gui/ page - #282

Merged
T-Crypt merged 2 commits into
nextfrom
T-Crypt/board-card-picker
Oct 31, 2026
Merged

T-Crypt merged 2 commits into
nextfrom
T-Crypt/board-card-picker

Conversation

@T-Crypt

@T-Crypt T-Crypt commented Oct 31, 2026

Copy link
Copy Markdown
Owner

Fourth slice of v0.5: per-card gateway endpoints.

What changes for users

On a node with several cards, the gateway's /gui/ page (the phone switchboard) shows each engine's card next to its name. Since #278, a model can have one engine entry per card, so launching qwen-gpu1 instead of qwen-gpu0 is how you pick the card from a phone. On a one-card node the page looks exactly as before.

GET /v1/berth/board now gives scripts and boards the same facts:

The harbor's own SWITCH tab (board plan step 5) is still to come. This slice puts the card into the data that tab will read, and into the board phones use today.

How

  • guiRow gains cards, filled from node.CardsOf(status, e.GPU) in guiRows. The board embeds guiRow, so /gui/state and the board get the field from one place.
  • boardCard gains base (left out for a berthd too old to name its cards) and cordoned.
  • index.js fills a .gpu chip per row and shows it only when the rows span more than one card.

Proof

  • TestBoardNamesEachEnginesCard (two cards, gpu1 cordoned): each card's base and cordoned are checked, and so are each engine's cards on both the board and /gui/state, for a name, a PCI address and an entry with no gpu. It fails before the feature commit.
  • Browser: Chromium through Playwright, against the real GUIHandler on the test's two-card berthd, at phone (390x844) and desktop (1280x800) sizes. Chips read gpu0, gpu1 and gpu0, no row header overflows, and each chip is 44 px wide. The first run caught a bug: the chip's class collided with the page's .card panel and stretched across the row. The fix names it .gpu. On a one-card daemon, every chip stays hidden.
  • Build, gofmt, vet, go test ./..., the Windows build and vet, and golangci-lint (0 issues) all pass.

On a two-card node with gpu1 cordoned, GET /v1/berth/board must give each
card its base URL and cordon, and each engine the cards its entry runs on,
a PCI address and a missing gpu key included. /gui/state must carry the
same cards per engine. Fails until the board and the rows carry them.
guiRow carries the cards an engine's entry runs on, from berthd's status,
so GET /v1/berth/board and /gui/state both name them. Each board card
gets its base URL on the gateway and its cordon. The /gui/ page shows each
row's card as a chip when the rows span more than one card, so launching
the copy of a model on gpu1 picks that card from a phone. One card, or
berthd not answering, shows no chip.

Fourth slice of v0.5, per-card gateway endpoints.
@T-Crypt
T-Crypt merged commit bd0d8bc into next Oct 31, 2026
4 checks passed
@T-Crypt
T-Crypt deleted the T-Crypt/board-card-picker branch October 31, 2026 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant