Update model picker to group language models by providers (from IPC) (#141)
This commit is contained in:
@@ -94,18 +94,10 @@ export function ModelPicker({
|
|||||||
|
|
||||||
const modelDisplayName = getModelDisplayName();
|
const modelDisplayName = getModelDisplayName();
|
||||||
|
|
||||||
// Flatten the cloud models from all providers
|
// Get auto provider models (if any)
|
||||||
const cloudModels =
|
const autoModels =
|
||||||
!providersLoading && modelsByProviders
|
!providersLoading && modelsByProviders && modelsByProviders["auto"]
|
||||||
? Object.entries(modelsByProviders).flatMap(([providerId, models]) =>
|
? modelsByProviders["auto"]
|
||||||
models.map((model) => ({
|
|
||||||
name: model.apiName,
|
|
||||||
displayName: model.displayName,
|
|
||||||
description: model.description || "",
|
|
||||||
tag: model.tag,
|
|
||||||
provider: providerId as ModelProvider,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
// Determine availability of local models
|
// Determine availability of local models
|
||||||
@@ -130,58 +122,127 @@ export function ModelPicker({
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="w-64" align="start">
|
<DropdownMenuContent className="w-64" align="start">
|
||||||
{" "}
|
|
||||||
{/* Increased width slightly */}
|
|
||||||
<DropdownMenuLabel>Cloud Models</DropdownMenuLabel>
|
<DropdownMenuLabel>Cloud Models</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
|
|
||||||
{/* Cloud models - loading state */}
|
{/* Cloud models - loading state */}
|
||||||
{providersLoading ? (
|
{providersLoading ? (
|
||||||
<div className="text-xs text-center py-2 text-muted-foreground">
|
<div className="text-xs text-center py-2 text-muted-foreground">
|
||||||
Loading models...
|
Loading models...
|
||||||
</div>
|
</div>
|
||||||
) : cloudModels.length === 0 ? (
|
) : !modelsByProviders ||
|
||||||
|
Object.keys(modelsByProviders).length === 0 ? (
|
||||||
<div className="text-xs text-center py-2 text-muted-foreground">
|
<div className="text-xs text-center py-2 text-muted-foreground">
|
||||||
No cloud models available
|
No cloud models available
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
/* Cloud models loaded */
|
/* Cloud models loaded */
|
||||||
cloudModels.map((model) => (
|
<>
|
||||||
<Tooltip key={`${model.provider}-${model.name}`}>
|
{/* Auto models at top level if any */}
|
||||||
<TooltipTrigger asChild>
|
{autoModels.length > 0 && (
|
||||||
<DropdownMenuItem
|
<>
|
||||||
className={
|
{autoModels.map((model) => (
|
||||||
selectedModel.provider === model.provider &&
|
<Tooltip key={`auto-${model.apiName}`}>
|
||||||
selectedModel.name === model.name
|
<TooltipTrigger asChild>
|
||||||
? "bg-secondary"
|
<DropdownMenuItem
|
||||||
: ""
|
className={
|
||||||
}
|
selectedModel.provider === "auto" &&
|
||||||
onClick={() => {
|
selectedModel.name === model.apiName
|
||||||
onModelSelect({
|
? "bg-secondary"
|
||||||
name: model.name,
|
: ""
|
||||||
provider: model.provider,
|
}
|
||||||
});
|
onClick={() => {
|
||||||
setOpen(false);
|
onModelSelect({
|
||||||
}}
|
name: model.apiName,
|
||||||
>
|
provider: "auto",
|
||||||
<div className="flex justify-between items-start w-full">
|
});
|
||||||
<span className="flex flex-col items-start">
|
setOpen(false);
|
||||||
<span>{model.displayName}</span>
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-start w-full">
|
||||||
|
<span className="flex flex-col items-start">
|
||||||
|
<span>{model.displayName}</span>
|
||||||
|
<span className="text-xs text-muted-foreground">
|
||||||
|
auto
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
{model.tag && (
|
||||||
|
<span className="text-[10px] bg-primary/10 text-primary px-1.5 py-0.5 rounded-full font-medium">
|
||||||
|
{model.tag}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
{model.description}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
{Object.keys(modelsByProviders).length > 1 && (
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Group other providers into submenus */}
|
||||||
|
{Object.entries(modelsByProviders).map(([providerId, models]) => {
|
||||||
|
// Skip auto provider as it's already handled
|
||||||
|
if (providerId === "auto") return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownMenuSub key={providerId}>
|
||||||
|
<DropdownMenuSubTrigger className="w-full font-normal">
|
||||||
|
<div className="flex flex-col items-start">
|
||||||
|
<span>{providerId}</span>
|
||||||
<span className="text-xs text-muted-foreground">
|
<span className="text-xs text-muted-foreground">
|
||||||
{model.provider}
|
{models.length} models
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
{model.tag && (
|
</DropdownMenuSubTrigger>
|
||||||
<span className="text-[10px] bg-primary/10 text-primary px-1.5 py-0.5 rounded-full font-medium">
|
<DropdownMenuSubContent className="w-56">
|
||||||
{model.tag}
|
<DropdownMenuLabel>{providerId} Models</DropdownMenuLabel>
|
||||||
</span>
|
<DropdownMenuSeparator />
|
||||||
)}
|
{models.map((model) => (
|
||||||
</div>
|
<Tooltip key={`${providerId}-${model.apiName}`}>
|
||||||
</DropdownMenuItem>
|
<TooltipTrigger asChild>
|
||||||
</TooltipTrigger>
|
<DropdownMenuItem
|
||||||
<TooltipContent side="right">{model.description}</TooltipContent>
|
className={
|
||||||
</Tooltip>
|
selectedModel.provider === providerId &&
|
||||||
))
|
selectedModel.name === model.apiName
|
||||||
|
? "bg-secondary"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
onModelSelect({
|
||||||
|
name: model.apiName,
|
||||||
|
provider: providerId as ModelProvider,
|
||||||
|
});
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-start w-full">
|
||||||
|
<span>{model.displayName}</span>
|
||||||
|
{model.tag && (
|
||||||
|
<span className="text-[10px] bg-primary/10 text-primary px-1.5 py-0.5 rounded-full font-medium">
|
||||||
|
{model.tag}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="right">
|
||||||
|
{model.description}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</DropdownMenuSubContent>
|
||||||
|
</DropdownMenuSub>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
{/* Local Models Parent SubMenu */}
|
{/* Local Models Parent SubMenu */}
|
||||||
<DropdownMenuSub>
|
<DropdownMenuSub>
|
||||||
|
|||||||
Reference in New Issue
Block a user