feat(web): add image version selectors to both launchers - #490
Conversation
Offer only the versions actually staged on the profile, so a selection can always run, and send the choice as image_ref. Pre-select the configured default rather than the newest staged tag: the pre-selection should change when someone changes config, not because an admin staged a new image. Fall back to the first staged tag when that default is missing from disk. The two launchers resolve different images. Services map their hyphenated pipeline name to a config.IMAGES key; batch jobs always use tigerflow_ml, since every task runs in that container regardless of TASKS[].service, which is an HF pipeline tag for filtering models. Block the batch Model step only when discovery succeeded and reported nothing staged — the job would fail its pre-flight, so stop there rather than four steps later. An unreachable profile still launches on the backend default. Closes #483.
ReviewNicely scoped, and the write-up in the PR description does a lot of the reviewer's work (the two-empty-cases table and the
|
Seeding `selected` in one effect and lifting it in another let the lift fire first on a container change — with the new repo but the previous tag, emitting a reference that does not exist. Derive the selection instead, so the two can never disagree, and keep only the user's explicit pick in state. Collapse the selector into Advanced Options in both launchers. The configured default is right for almost everyone; pinning is a reproducibility need, so it should not invite casual changes. Local service profiles gain an Advanced section, since they run containers too, and the batch wizard gets one on its Model step, the only step both profile types share. Extract isNoContainerStaged so the step-blocking rule is testable, and use replaceAll for the pipeline-to-image-key conversion.
|
Triage of the automated review — all three addressed (ba29e7b). Effect ordering — confirmed real, and I could reproduce it. Instrumented the container switch and captured every That first reference does not exist, and it would be the pinned value if a submit landed in that window. Fixed by deriving the selection from Added a regression test that asserts every call is correct, not just the last — Step-blocking coverage. Extracted Non-global Separately, on review feedback the selector has moved into Advanced Options in both launchers. The configured default is correct for almost everyone, and pinning is a reproducibility need rather than a routine choice — a prominent control invited changing something that can only make things worse for a casual user. This also meant adding an Advanced section to the local-profile branch of the service form (local profiles run containers too) and one to the batch wizard's Model step, the only step both profile types share. The PR description has been updated. 527 tests passing; 0 lint errors. |
Expanding Advanced or Deployment Options below the fold revealed nothing until the user scrolled, so the click looked like it had done nothing. The batch launcher already scrolled; the service launcher never did. Share one useScrollOnExpand hook rather than repeating the effect in each of the four disclosures. The modal owns the scroll container and passes it down by context, since the collapsible sections live in nested forms. Also covers the batch Model step's new section, and clears the pending timeout on collapse, which the original batch effect did not.
Summary
GET /api/containers, Add GET /api/containers to list staged container images per profile #482) so a selection can always run. The choice is sent asimage_ref, which the backend persists and reuses across restarts (Persist and honor a pinned container image (image_ref) #480).config.IMAGESkey (text-generation→text_generation), while batch jobs always usetigerflow_ml.TASKS[].serviceis an HF pipeline tag used to filter which models to offer (image-text-to-text,object-detection) — it is not an image key, and every batch task runs the tigerflow-ml container regardless (jobs/base.pyresolvesimages["tigerflow_ml"]with no task branch).This is the last of four sub-issues under #212, so image version pinning is now complete end to end: select a version, it is recorded, restarts reuse it, and the CLI and UI show it.
Behavior worth reviewing
Two empty cases, handled oppositely. They look the same in the UI but mean different things, and the route distinguishes them:
containerundefined{tags: []}The second case would otherwise fail at pre-flight with "tigerflow-ml image not found" after the user filled in all four wizard steps. Blocking early is the friendlier failure. Note this deliberately does not gate the step on
imageRefbeing set, which would have conflated the two cases and broken the unreachable path.A single staged version still renders a select, matching
RevisionSelect, rather than hiding below two options. Consistency beats a special rule the user would have to learn; disabling one-option selects uniformly is tracked in #489.Hyphen conversion uses
replaceAll.runServiceuses a non-globalreplace, which would turnimage-text-to-textintoimage_text-to-text. That is latent today — onlyspeech_recognitionandtext_generationare launchable services and both have a single hyphen — but the new code should not inherit it.Test plan
npm run lint— 0 errors (one pre-existing warning in an untouched file).npm test— 522 passed across 53 files (9 new).ImageVersionSelect.test.jsxcovers: pre-selecting the configured default (using a container where the default is deliberately not the newest tag, so the assertion is meaningful), lifting the fullrepo:tag, falling back when the default is unstaged, rendering nothing when unreachable and when nothing is staged, keeping a single-option select, re-seeding on a container change, and not crashing without a setter.ServiceModal.test.jsxneeded both auseStagedContainersmock (the auto-mock returnsundefinedand crashes on destructure) and an updatedrunServicepayload assertion for the new argument.Closes #483.