fix: vision slot filters to image-capable + custom models (was relaxing for all providers)
The prior change made the vision slot show every model (image-capable first), which relaxed the filter for built-in providers too — built-in text-only models became selectable for Vision. Centralize the vision rule in ModelMenuList: built-ins must report image input; custom-endpoint models stay selectable (their capability may be unreported). Image-capable still float first.
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import type { ModelCatalogEntry } from "@/src/core";
|
||||
import { fuzzyScore, subscriptionLabel } from "@/src/core";
|
||||
import { CUSTOM_PROVIDER, fuzzyScore, subscriptionLabel } from "@/src/core";
|
||||
import { formatTokens } from "@/components/usage-format";
|
||||
import { SearchMenuList } from "./search-menu-list";
|
||||
|
||||
@@ -39,7 +39,7 @@ export function ModelMenuList({
|
||||
effectiveProvider,
|
||||
onPick,
|
||||
footer,
|
||||
prioritizeImage,
|
||||
vision,
|
||||
}: {
|
||||
/** The full catalog — undefined while it loads. */
|
||||
models: ModelCatalogEntry[] | undefined;
|
||||
@@ -54,19 +54,25 @@ export function ModelMenuList({
|
||||
onPick: (entry: ModelCatalogEntry) => void;
|
||||
/** Quiet footer note under the list (context-specific). */
|
||||
footer?: string;
|
||||
/** Vision slot: image-capable models float to the top (still all
|
||||
* selectable — a custom endpoint that doesn't report modality must
|
||||
* stay pickable, so this orders rather than filters). */
|
||||
prioritizeImage?: boolean;
|
||||
/** Vision slot: only image-capable models are selectable — plus every
|
||||
* custom-endpoint model, whose capability the endpoint may not report.
|
||||
* Image-capable ones float to the top. */
|
||||
vision?: boolean;
|
||||
}) {
|
||||
// Vision slot: built-ins must report image input; custom-endpoint models
|
||||
// stay selectable (the endpoint may not report a modality). Image-capable
|
||||
// ones float to the top of the list.
|
||||
const visionItems = vision
|
||||
? models?.filter((m) => m.input.includes("image") || m.provider === CUSTOM_PROVIDER.id)
|
||||
: models;
|
||||
return (
|
||||
<>
|
||||
<SearchMenuList
|
||||
items={models}
|
||||
items={visionItems}
|
||||
itemKey={(m) => `${m.provider}/${m.id}`}
|
||||
searchTerms={(m) => [m.provider, m.id, m.name]}
|
||||
compare={(a, b) => a.id.localeCompare(b.id)}
|
||||
prioritize={prioritizeImage ? (m) => m.input.includes("image") : undefined}
|
||||
prioritize={vision ? (m) => m.input.includes("image") : undefined}
|
||||
isSelected={(m) => m.id === effectiveId && m.provider === (effectiveProvider ?? m.provider)}
|
||||
onPick={onPick}
|
||||
searchTestid="model-search"
|
||||
|
||||
Reference in New Issue
Block a user