diff --git a/webui/src/components/thread/ModelPresetBadge.tsx b/webui/src/components/thread/ModelPresetBadge.tsx
index 224610ee3..de0dbc5bc 100644
--- a/webui/src/components/thread/ModelPresetBadge.tsx
+++ b/webui/src/components/thread/ModelPresetBadge.tsx
@@ -533,6 +533,7 @@ function PresetPill({
return (
- {label}
+ {needsSetup ? : label}
+
+
+ );
+}
+
+function SetupPromptLabel({ label }: { label: string }) {
+ const separator = label.indexOf(" ");
+ if (separator < 0) {
+ return {label};
+ }
+
+ return (
+
+
+ {label.slice(0, separator)}
+
+ {" "}
+
+ {label.slice(separator + 1)}
);
diff --git a/webui/src/globals.css b/webui/src/globals.css
index cd7b7d9c1..a83f98c0a 100644
--- a/webui/src/globals.css
+++ b/webui/src/globals.css
@@ -735,6 +735,36 @@
transform: scale(0.98);
}
+.composer-model-pill-setup {
+ border-color: hsl(var(--border) / 0.72);
+ box-shadow:
+ inset 0 1px 0 rgb(255 255 255 / 0.62),
+ 0 1px 2px hsl(var(--foreground) / 0.035);
+ transition-property: color, background-color, border-color, box-shadow, transform;
+ transition-duration: 180ms;
+ transition-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
+}
+
+.dark .composer-model-pill-setup {
+ box-shadow:
+ inset 0 1px 0 rgb(255 255 255 / 0.045),
+ 0 1px 2px rgb(0 0 0 / 0.12);
+}
+
+.thread-composer-model-badge:hover > .composer-model-pill-setup {
+ border-color: hsl(var(--border));
+ background-color: hsl(var(--accent) / 0.7);
+ box-shadow:
+ inset 0 1px 0 rgb(255 255 255 / 0.72),
+ 0 2px 5px hsl(var(--foreground) / 0.06);
+}
+
+.dark .thread-composer-model-badge:hover > .composer-model-pill-setup {
+ box-shadow:
+ inset 0 1px 0 rgb(255 255 255 / 0.07),
+ 0 2px 5px rgb(0 0 0 / 0.16);
+}
+
@keyframes composer-model-pill-viewport-enter {
from {
transform: scale(0.9074);
@@ -783,6 +813,10 @@
transform: none !important;
}
+ .composer-model-pill-setup {
+ transition: none;
+ }
+
.composer-model-pill-track[data-settling="true"],
.composer-model-pill-dock {
transition: none;
diff --git a/webui/src/tests/thread-shell.test.tsx b/webui/src/tests/thread-shell.test.tsx
index 67905a92e..cca9cb52a 100644
--- a/webui/src/tests/thread-shell.test.tsx
+++ b/webui/src/tests/thread-shell.test.tsx
@@ -876,6 +876,10 @@ describe("ThreadShell", () => {
const badge = await screen.findByRole("button", { name: "Choose your AI" });
expect(screen.queryByTestId("composer-model-setup-icon")).not.toBeInTheDocument();
+ expect(badge.querySelector('[data-needs-setup="true"]')).toHaveClass(
+ "composer-model-pill-setup",
+ );
+ expect(screen.getByTestId("composer-model-setup-label")).toHaveTextContent("Choose your AI");
expect(badge).not.toHaveClass("border-amber-500/35");
expect(screen.queryByTestId("composer-model-logo-openai_codex")).not.toBeInTheDocument();
fireEvent.click(badge);