From b2a10e5477dafd23981d07e2781fb861b7ad349e Mon Sep 17 00:00:00 2001
From: Aarav Sareen <96787824+arvsrn@users.noreply.github.com>
Date: Fri, 23 Oct 2026 16:08:40 +0530
Subject: [PATCH] fix(app): disambiguate workspace models and polish new model
picker (#58419)
---
.../providers/models/select-dialog-next.css | 31 +++++------
.../providers/models/select-dialog-next.tsx | 52 +++++++++++++++----
2 files changed, 55 insertions(+), 28 deletions(-)
diff --git a/packages/app/src/providers/models/select-dialog-next.css b/packages/app/src/providers/models/select-dialog-next.css
index 4250f612e96..f76963f1730 100644
--- a/packages/app/src/providers/models/select-dialog-next.css
+++ b/packages/app/src/providers/models/select-dialog-next.css
@@ -44,7 +44,7 @@
background: transparent;
}
- /* The 24px manage button sits 2px from every edge of the 28px row. */
+ /* The 24px buttons sit 2px from every edge of the 28px row. */
[data-component="search-list"] [data-slot="text-input-v2-trailing"] {
margin-inline-end: 0;
@@ -53,13 +53,14 @@
}
}
- [data-component="search-list"] [data-slot="text-input-v2-leading-icon"] {
- display: none;
+ /* Like a model row: 6px inset, a 16px icon slot and a 6px gap, so the query starts where the model names do. */
+ [data-component="search-list"] [data-slot="search-list-search"] [data-slot="text-input-v2-value"] {
+ gap: 6px;
}
- /* Row inset, check slot and gap: the query starts where the model names do. */
- [data-component="search-list"] [data-slot="text-input-v2-input"] {
- padding-inline-start: 22px;
+ [data-component="search-list"] [data-slot="search-list-search"] [data-slot="text-input-v2-leading-icon"] {
+ width: 22px;
+ padding-inline-start: 6px;
}
/* The stuck header's gradient replaces it; the list measures sections for it, and here they have no box. */
@@ -69,7 +70,7 @@
/* Arrow keys keep the active row clear of the stuck header. */
[data-component="search-list"] [data-slot="search-list-scroll"] > .scroll-view__viewport {
- scroll-padding-top: 32px;
+ scroll-padding-top: 36px;
}
[data-component="search-list"] [data-slot="search-list-results"] {
@@ -91,10 +92,10 @@
*/
[data-component="search-list"] [data-slot="search-list-header"] {
height: auto;
- padding-block: 12px 2px;
- padding-inline: 28px 6px;
+ padding-block: 16px 2px;
+ padding-inline: 34px 6px;
background: var(--v2-background-bg-base);
- color: var(--v2-text-text-muted);
+ color: var(--v2-text-text-faint);
font-size: 12px;
line-height: 18px;
@@ -141,17 +142,11 @@
}
}
- [data-component="search-list"]
- [data-slot="search-list-section"]:first-child
- > [data-slot="search-list-header"] {
- padding-top: 16px;
- }
-
[data-component="search-list"] [data-slot="search-list-row"] {
justify-content: flex-start;
- gap: 3px;
+ gap: 6px;
height: 28px;
- padding-inline: 3px;
+ padding-inline: 6px 3px;
border-radius: 6px;
font-size: 13px;
font-weight: 440;
diff --git a/packages/app/src/providers/models/select-dialog-next.tsx b/packages/app/src/providers/models/select-dialog-next.tsx
index 6004b5bb61d..bc0ff254d25 100644
--- a/packages/app/src/providers/models/select-dialog-next.tsx
+++ b/packages/app/src/providers/models/select-dialog-next.tsx
@@ -670,6 +670,14 @@ export function DialogSelectModelNext(props: { provider?: string; model?: ModelS
void dialog.show(() => )
}
+ const location = useWorkspaceLocation()
+
+ const connect = async () => {
+ const { DialogConnectProvider } = await import("@/providers/connect/dialog")
+ // The model chosen after connecting applies to this composer.
+ void dialog.show(() => )
+ }
+
const triangle = createSafeTriangle({
flyout: () => (flyoutItem() && flyoutRef?.isConnected ? flyoutRef : undefined),
})
@@ -913,9 +921,12 @@ export function DialogSelectModelNext(props: { provider?: string; model?: ModelS
- {/* Favorites and Recent mix providers, so their rows name one. */}
+ {/* Favorites and Recent mix providers, so their rows name one, with its workspace when its header has one. */}
{labels.name(item().provider)}
+
+ {(workspace) => {workspace()}}
+
{language.t("model.tag.free")}
@@ -964,14 +975,29 @@ export function DialogSelectModelNext(props: { provider?: string; model?: ModelS
onQuery={setSearch}
placeholder={language.t("dialog.model.search.placeholder")}
trailing={
-
- }
- aria-label={language.t("dialog.model.manage")}
- onClick={manage}
- />
-
+ <>
+
+ }
+ aria-label={language.t("command.provider.connect")}
+ onClick={connect}
+ />
+
+
+ }
+ aria-label={language.t("dialog.model.manage")}
+ onClick={manage}
+ />
+
+ >
}
items={rows()}
key={(row) => row.id}
@@ -1044,7 +1070,13 @@ export function DialogSelectModelNext(props: { provider?: string; model?: ModelS
-
+ {/* The full name, "Workspace / Provider", where a workspace badge tells the connections apart. */}
+
)}