feat(model-selector, model-connections-settings): integrate AUTO provider icon and streamline auto mode option rendering

This commit is contained in:
Anish Sarkar 2026-06-13 13:21:21 +05:30
parent bd4a04f2e7
commit 6d7732436d
3 changed files with 25 additions and 14 deletions

View file

@ -1,7 +1,7 @@
"use client"; "use client";
import { useAtom, useAtomValue } from "jotai"; import { useAtom, useAtomValue } from "jotai";
import { Check, ChevronDown, Cpu, Search, Settings2, Zap } from "lucide-react"; import { Check, ChevronDown, Search, Settings2 } from "lucide-react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import type { UIEvent } from "react"; import type { UIEvent } from "react";
import { useCallback, useMemo, useState } from "react"; import { useCallback, useMemo, useState } from "react";
@ -26,7 +26,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover
import { Spinner } from "@/components/ui/spinner"; import { Spinner } from "@/components/ui/spinner";
import type { ConnectionRead, ModelRead } from "@/contracts/types/model-connections.types"; import type { ConnectionRead, ModelRead } from "@/contracts/types/model-connections.types";
import { useIsMobile } from "@/hooks/use-mobile"; import { useIsMobile } from "@/hooks/use-mobile";
import { getProviderIcon } from "@/lib/provider-icons"; import { AUTO_PROVIDER_ICON_KEY, getProviderIcon } from "@/lib/provider-icons";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { providerDisplay } from "../settings/model-connections/provider-metadata"; import { providerDisplay } from "../settings/model-connections/provider-metadata";
@ -153,13 +153,10 @@ export function ModelSelector({
className="flex w-full items-center justify-between rounded-md px-3 py-2 text-left transition-colors hover:bg-accent hover:text-accent-foreground" className="flex w-full items-center justify-between rounded-md px-3 py-2 text-left transition-colors hover:bg-accent hover:text-accent-foreground"
onClick={() => selectModel(0)} onClick={() => selectModel(0)}
> >
<div className="flex items-center gap-3"> <div className="min-w-0 flex-1">
<div className="flex h-8 w-8 items-center justify-center rounded-md bg-primary/10 text-primary"> <div className="flex min-w-0 items-center gap-2 font-medium">
<Zap className="h-4 w-4" /> {getProviderIcon(AUTO_PROVIDER_ICON_KEY, { className: "size-4 shrink-0" })}
</div> <span className="truncate">Auto</span>
<div>
<div className="font-medium">Auto</div>
<div className="text-xs text-muted-foreground">Use the hosted/global router</div>
</div> </div>
</div> </div>
{(roles?.chat_model_id ?? 0) === 0 ? <Check className="h-4 w-4" /> : null} {(roles?.chat_model_id ?? 0) === 0 ? <Check className="h-4 w-4" /> : null}
@ -252,7 +249,7 @@ export function ModelSelector({
{selected ? ( {selected ? (
getProviderIcon(selected.provider, { className: "size-4 shrink-0" }) getProviderIcon(selected.provider, { className: "size-4 shrink-0" })
) : ( ) : (
<Cpu className="h-4 w-4 shrink-0" /> getProviderIcon(AUTO_PROVIDER_ICON_KEY, { className: "size-4 shrink-0" })
)} )}
<span className="min-w-0 flex-1 truncate text-sm"> <span className="min-w-0 flex-1 truncate text-sm">
{selected ? modelName(selected) : "Auto"} {selected ? modelName(selected) : "Auto"}

View file

@ -18,6 +18,7 @@ import {
} from "@/components/ui/select"; } from "@/components/ui/select";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import type { ConnectionRead, ModelRead } from "@/contracts/types/model-connections.types"; import type { ConnectionRead, ModelRead } from "@/contracts/types/model-connections.types";
import { AUTO_PROVIDER_ICON_KEY, getProviderIcon } from "@/lib/provider-icons";
import { ModelProviderConnectionsPanel } from "./model-connections/model-provider-connections-panel"; import { ModelProviderConnectionsPanel } from "./model-connections/model-provider-connections-panel";
import { capability, modelLabel } from "./model-connections/model-utils"; import { capability, modelLabel } from "./model-connections/model-utils";
import { providerDisplay, providerIcon } from "./model-connections/provider-metadata"; import { providerDisplay, providerIcon } from "./model-connections/provider-metadata";
@ -38,6 +39,17 @@ function roleSelectValue(modelId: number | null | undefined, models: Array<{ id:
return models.some((model) => model.id === modelId) ? String(modelId) : "0"; return models.some((model) => model.id === modelId) ? String(modelId) : "0";
} }
function renderAutoModeOption() {
return (
<SelectItem value="0">
<span className="inline-flex items-center gap-2">
{getProviderIcon(AUTO_PROVIDER_ICON_KEY)}
<span>Auto mode</span>
</span>
</SelectItem>
);
}
export function ModelConnectionsSettings({ searchSpaceId }: { searchSpaceId: number }) { export function ModelConnectionsSettings({ searchSpaceId }: { searchSpaceId: number }) {
const [{ data: globalConnections = [] }] = useAtom(globalModelConnectionsAtom); const [{ data: globalConnections = [] }] = useAtom(globalModelConnectionsAtom);
const [{ data: connections = [] }] = useAtom(modelConnectionsAtom); const [{ data: connections = [] }] = useAtom(modelConnectionsAtom);
@ -90,7 +102,7 @@ export function ModelConnectionsSettings({ searchSpaceId }: { searchSpaceId: num
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="0">Auto mode</SelectItem> {renderAutoModeOption()}
{chatModels.map(renderModelOption)} {chatModels.map(renderModelOption)}
</SelectContent> </SelectContent>
</Select> </Select>
@ -109,7 +121,7 @@ export function ModelConnectionsSettings({ searchSpaceId }: { searchSpaceId: num
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="0">Auto mode</SelectItem> {renderAutoModeOption()}
{visionModels.map(renderModelOption)} {visionModels.map(renderModelOption)}
</SelectContent> </SelectContent>
</Select> </Select>
@ -125,7 +137,7 @@ export function ModelConnectionsSettings({ searchSpaceId }: { searchSpaceId: num
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="0">Auto mode</SelectItem> {renderAutoModeOption()}
{imageModels.map(renderModelOption)} {imageModels.map(renderModelOption)}
</SelectContent> </SelectContent>
</Select> </Select>

View file

@ -38,6 +38,8 @@ import {
} from "@/components/icons/providers"; } from "@/components/icons/providers";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
export const AUTO_PROVIDER_ICON_KEY = "AUTO";
/** /**
* Returns a Lucide icon element for the given LLM / image-gen provider. * Returns a Lucide icon element for the given LLM / image-gen provider.
* Accepts an optional `className` override for the icon size. * Accepts an optional `className` override for the icon size.
@ -46,7 +48,7 @@ export function getProviderIcon(
provider: string, provider: string,
{ isAutoMode, className = "size-4" }: { isAutoMode?: boolean; className?: string } = {} { isAutoMode, className = "size-4" }: { isAutoMode?: boolean; className?: string } = {}
) { ) {
if (isAutoMode || provider?.toUpperCase() === "AUTO") { if (isAutoMode || provider?.toUpperCase() === AUTO_PROVIDER_ICON_KEY) {
return <Shuffle className={cn(className, "text-muted-foreground")} />; return <Shuffle className={cn(className, "text-muted-foreground")} />;
} }