diff --git a/studio/frontend/src/features/settings/tabs/agents-tab.tsx b/studio/frontend/src/features/settings/tabs/agents-tab.tsx index d810048a86..c4c464d62a 100644 --- a/studio/frontend/src/features/settings/tabs/agents-tab.tsx +++ b/studio/frontend/src/features/settings/tabs/agents-tab.tsx @@ -1113,233 +1113,240 @@ export function AgentsTab() { aria-label={t("settings.agents.commandBuilder")} className="flex w-full flex-col gap-6" > -
-
-
+ {/* Keyed to this pane, not the viewport. The dialog leaves the tab + about 440px at a 768px window, where three columns crush the agent + and model controls; 34rem is the point all three stay usable. */} +
+
+
+
+ + {t("settings.agents.agent")} + + + {t("settings.agents.docs")} + + +
+ +
+ + - { + chosenVariant.current = { model: selectedModel, variant }; + setSelectedVariant(variant); + resetCopied(); + }} + disabled={variantsLoading || variants.length === 0} + > + + + {selectedVariant} + + + + {variants.map((variant) => { + // Size only: the recommended/downloaded tags wrapped every + // row onto two lines and made the list hard to scan. + const size = formatBytes( + variant.download_size_bytes ?? variant.size_bytes, + ); + return ( + + + {variant.quant} + + {size ? ( + + {size} ) : null} - - - ); - })} - - -
- -
- - {t("settings.agents.model")} - - { - setModelPickerOpen(open); - if (!open) { - setModelSearch(""); - } - }} - > - - - - - - - - {t("settings.agents.noModels")} - {visibleModels.map((model) => ( - { - modelSelectionChanged.current = true; - setSelectedModel(model); - setSelectedVariant(knownVariants[model] ?? null); - setVariants([]); - setVariantsFailed(false); - setVariantsLoading(isHuggingFaceRepo(model)); - setModelSearch(""); - setModelPickerOpen(false); - resetCopied(); - }} - className="cursor-pointer font-mono text-xs" - > - - {labelFor(model)} - - - ))} - - {matchingModels.length > visibleModels.length ? ( -

- {t("settings.agents.showingModels", { - shown: visibleModels.length, - total: matchingModels.length, - })} -

- ) : null} -
-
-
-
- -
- - {t("settings.agents.quantization")} - - + + ); + })} + + +
diff --git a/studio/frontend/src/features/settings/tabs/resources-tab.tsx b/studio/frontend/src/features/settings/tabs/resources-tab.tsx index 8ac51f3e38..7725aaa0ad 100644 --- a/studio/frontend/src/features/settings/tabs/resources-tab.tsx +++ b/studio/frontend/src/features/settings/tabs/resources-tab.tsx @@ -456,9 +456,7 @@ export function ResourcesTab() {
)} - {/* Sized against this pane, not the viewport: the Settings dialog caps - the tab at roughly 650px however wide the window is. */} -
+
{hasGpu ? ( metrics.devices.map((device, index) => { const ordinal = deviceOrdinal(device); @@ -490,29 +488,37 @@ export function ResourcesTab() { ? formatPercent(safePercent) : unknownLabel; return ( - // One row per device: a full-width bar under a single GPU read - // as a page-wide rule, so the bar is sized to the row instead. + // Two compact lines per device. The settings pane is about + // 664px at any window size, which cannot hold the name, three + // figures, meter and percentage on one row, so no breakpoint + // would ever fire. Splitting them keeps the name readable and + // the meter narrow instead of running the width of the pane.
-
-
- {device.name ?? t("settings.resources.gpu.unknownDevice")} +
+
+
+ {device.name ?? + t("settings.resources.gpu.unknownDevice")} +
+
+ {ordinal === undefined + ? backendLabel + : `${t("settings.resources.gpu.deviceWithIndex", { + index: ordinal, + })}, ${backendLabel}`} +
-
- {ordinal === undefined - ? backendLabel - : `${t("settings.resources.gpu.deviceWithIndex", { - index: ordinal, - })}, ${backendLabel}`} +
+ {percentText}{" "} + {t("settings.resources.gpu.vramUtilization")}
- {/* Stacked until the pane is genuinely wide enough: the - figures, meter and percentage need about 50rem before the - name has room left to read. */} -
-
+ {/* Wraps rather than overflows once the pane gets narrow. */} +
+
{t("settings.resources.gpu.used", { value: usedText })} @@ -525,20 +531,12 @@ export function ResourcesTab() { })}
-
- {/* Fills the space left by the percentage rather than - claiming the full row, which overflowed once stacked. */} - -
- {percentText}{" "} - {t("settings.resources.gpu.vramUtilization")} -
-
+
); diff --git a/studio/frontend/src/index.css b/studio/frontend/src/index.css index 34897c08bc..e298dbbe8c 100644 --- a/studio/frontend/src/index.css +++ b/studio/frontend/src/index.css @@ -671,6 +671,13 @@ html[data-chat-font] .aui-root { border-color: transparent; } +/* The card removes its outline, so the border is the only focus indicator. + This rule is unlayered like the one above, which would otherwise beat + Tailwind's layered focus-visible:border-ring and leave nothing visible. */ +.dark .palette-card:focus-visible { + border-color: var(--ring); +} + .palette-card:hover { border-color: var(--ring-soft); }