Merge PR #62 contribution for donor-led integration

This commit is contained in:
amosblomqvist
2026-10-29 02:25:19 +02:00
20 changed files with 1690 additions and 72 deletions
+14 -2
View File
@@ -21,7 +21,7 @@
import { useEffect, useRef, useState } from "react";
import type { ModelCatalogEntry } from "@/src/core";
import { CLAUDE_CODE_PROVIDER, fuzzyScore, subscriptionLabel } from "@/src/core";
import { CLAUDE_CODE_PROVIDER, CUSTOM_PROVIDER, fuzzyScore, subscriptionLabel } from "@/src/core";
import { formatTokens } from "@/components/usage-format";
import { SearchMenuList } from "./search-menu-list";
@@ -40,6 +40,7 @@ export function ModelMenuList({
effectiveProvider,
onPick,
footer,
vision,
}: {
/** The full catalog — undefined while it loads. */
models: ModelCatalogEntry[] | undefined;
@@ -54,14 +55,25 @@ export function ModelMenuList({
onPick: (entry: ModelCatalogEntry) => void;
/** Quiet footer note under the list (context-specific). */
footer?: string;
/** 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={vision ? (m) => m.input.includes("image") : undefined}
isSelected={(m) => m.id === effectiveId && m.provider === (effectiveProvider ?? m.provider)}
onPick={onPick}
searchTestid="model-search"