import { jsx, jsxs } from "react/jsx-runtime";
import {
  useState,
  useEffect,
  forwardRef,
  useRef,
  useImperativeHandle,
  useMemo,
  useCallback
} from "react";
import { Box, Text } from "ink";
import { useTerminalSize } from "../../hooks/useTerminalSize.js";
import { getModelDisplayName, getReasoningProfile } from "@dexto/llm";
import {
  CodexAppServerClient,
  createCodexBaseURL,
  listOllamaModels,
  DEFAULT_OLLAMA_URL,
  getLocalModelById,
  getCuratedModelRefsForProviders,
  getOpenRouterModelCacheInfo,
  parseCodexBaseURL,
  refreshOpenRouterModelCache
} from "@dexto/core";
import {
  loadCustomModels,
  deleteCustomModel,
  getAllInstalledModels,
  loadGlobalPreferences,
  isDextoAuthEnabled,
  loadModelPickerState,
  toggleFavoriteModel,
  toModelPickerKey
} from "@dexto/agent-management";
import { getLLMProviderDisplayName } from "../../utils/llm-provider-display.js";
import { getMaxVisibleItemsForTerminalRows } from "../../utils/overlaySizing.js";
import { compareModelsLatestFirst, isDeprecatedModelStatus } from "../../utils/modelOrdering.js";
import {
  getCachedStringWidth,
  stripUnsafeCharacters,
  toCodePoints
} from "../../utils/textUtils.js";
import { HintBar } from "../shared/HintBar.js";
const FEATURED_SECTION_LIMIT = 8;
const MODEL_SELECTOR_TABS = [
  { id: "all-models", label: "All" },
  { id: "featured", label: "Featured" },
  { id: "recents", label: "Recents" },
  { id: "favorites", label: "Favorites" },
  { id: "custom", label: "Custom" }
];
const PROVIDER_COLLATOR = new Intl.Collator("en", { sensitivity: "base" });
const PROVIDER_TOKEN_PATTERN = /[^a-z0-9]/g;
const CODEX_CHATGPT_BASE_URL = createCodexBaseURL("chatgpt");
const CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS = 5e3;
function normalizeProviderToken(value) {
  return value.toLowerCase().replace(PROVIDER_TOKEN_PATTERN, "");
}
function isChatGPTCodexBaseURL(baseURL) {
  return parseCodexBaseURL(baseURL)?.authMode === "chatgpt";
}
function isChatGPTCodexConfig(provider, baseURL) {
  return provider === "openai-compatible" && isChatGPTCodexBaseURL(baseURL);
}
function canonicalizeModelBaseURL(baseURL) {
  const parsed = parseCodexBaseURL(baseURL);
  return parsed ? createCodexBaseURL(parsed.authMode) : baseURL;
}
function toCanonicalModelPickerKey(input) {
  const baseURL = canonicalizeModelBaseURL(input.baseURL);
  return toModelPickerKey({
    provider: input.provider,
    model: input.model,
    ...baseURL ? { baseURL } : {}
  });
}
function createModelIdentity(input) {
  return {
    provider: input.provider,
    name: input.name,
    ...input.baseURL ? { baseURL: input.baseURL } : {}
  };
}
async function raceWithTimeout(promise, options) {
  return await new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      options.onTimeout?.();
      reject(new Error(options.errorMessage));
    }, options.timeoutMs);
    promise.then(
      (value) => {
        clearTimeout(timer);
        resolve(value);
      },
      (error) => {
        clearTimeout(timer);
        reject(error);
      }
    );
  });
}
function matchesConfiguredModel(candidate, configured) {
  if (candidate.provider !== configured.provider || candidate.name !== configured.model) {
    return false;
  }
  const candidateBaseURL = candidate.baseURL ?? "";
  const configuredBaseURL = configured.baseURL ?? "";
  if (candidateBaseURL === configuredBaseURL) {
    return true;
  }
  const candidateCodex = parseCodexBaseURL(candidate.baseURL);
  const configuredCodex = parseCodexBaseURL(configured.baseURL);
  return candidateCodex?.authMode === configuredCodex?.authMode;
}
async function loadChatGPTCodexModels(agent) {
  let client = null;
  try {
    const createPromise = CodexAppServerClient.create({
      requestTimeoutMs: CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS
    });
    client = await raceWithTimeout(createPromise, {
      timeoutMs: CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS,
      errorMessage: `Timed out starting ChatGPT Codex model listing after ${CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS}ms`,
      onTimeout: () => {
        void createPromise.then((lateClient) => lateClient.close().catch(() => void 0)).catch(() => void 0);
      }
    });
    const account = await raceWithTimeout(client.readAccount(false), {
      timeoutMs: CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS,
      errorMessage: `Timed out reading ChatGPT Codex account state after ${CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS}ms`
    });
    if (account.account?.type !== "chatgpt") {
      return [];
    }
    return await raceWithTimeout(client.listModels(), {
      timeoutMs: CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS,
      errorMessage: `Timed out listing ChatGPT Codex models after ${CHATGPT_CODEX_MODEL_LIST_TIMEOUT_MS}ms`
    });
  } catch (error) {
    agent.logger.debug(
      `ChatGPT Codex model list unavailable: ${error instanceof Error ? error.message : String(error)}`
    );
    return [];
  } finally {
    if (client) {
      await client.close().catch(() => void 0);
    }
  }
}
function toReleaseDateLookupKey(provider, modelName) {
  return `${provider}::${modelName.toLowerCase()}`;
}
function splitGatewayModelName(modelName) {
  const slashIndex = modelName.indexOf("/");
  if (slashIndex <= 0 || slashIndex >= modelName.length - 1) {
    return null;
  }
  return {
    providerPrefix: modelName.slice(0, slashIndex),
    unprefixedName: modelName.slice(slashIndex + 1)
  };
}
function createReleaseDateResolver({
  allModels,
  providers
}) {
  const releaseDateByProviderAndName = /* @__PURE__ */ new Map();
  const releaseDateCandidatesByName = /* @__PURE__ */ new Map();
  const latestReleaseDateByName = /* @__PURE__ */ new Map();
  const providerByToken = /* @__PURE__ */ new Map();
  for (const provider of providers) {
    const token = normalizeProviderToken(provider);
    if (token && !providerByToken.has(token)) {
      providerByToken.set(token, provider);
    }
    const modelsForProvider = allModels[provider];
    if (!modelsForProvider || modelsForProvider.length === 0) {
      continue;
    }
    for (const model of modelsForProvider) {
      const releaseDate = model.releaseDate;
      if (!releaseDate) {
        continue;
      }
      const lowerName = model.name.toLowerCase();
      releaseDateByProviderAndName.set(
        toReleaseDateLookupKey(provider, lowerName),
        releaseDate
      );
      const existingLatest = latestReleaseDateByName.get(lowerName);
      if (!existingLatest || releaseDate > existingLatest) {
        latestReleaseDateByName.set(lowerName, releaseDate);
      }
      const candidates = releaseDateCandidatesByName.get(lowerName) ?? [];
      candidates.push({ provider, releaseDate });
      releaseDateCandidatesByName.set(lowerName, candidates);
    }
  }
  return (provider, modelName, explicitReleaseDate) => {
    if (explicitReleaseDate) {
      return explicitReleaseDate;
    }
    const lowerName = modelName.toLowerCase();
    const sameProviderDate = releaseDateByProviderAndName.get(
      toReleaseDateLookupKey(provider, lowerName)
    );
    if (sameProviderDate) {
      return sameProviderDate;
    }
    const openRouterDate = releaseDateByProviderAndName.get(
      toReleaseDateLookupKey("openrouter", lowerName)
    );
    if (openRouterDate) {
      return openRouterDate;
    }
    const parsedGatewayModel = splitGatewayModelName(modelName);
    if (!parsedGatewayModel) {
      return void 0;
    }
    const unprefixedName = parsedGatewayModel.unprefixedName.toLowerCase();
    const preferredProvider = providerByToken.get(
      normalizeProviderToken(parsedGatewayModel.providerPrefix)
    );
    if (preferredProvider) {
      const providerDate = releaseDateByProviderAndName.get(
        toReleaseDateLookupKey(preferredProvider, unprefixedName)
      );
      if (providerDate) {
        return providerDate;
      }
    }
    const candidates = releaseDateCandidatesByName.get(unprefixedName);
    if (candidates && preferredProvider) {
      const preferredProviderCandidate = candidates.find(
        (candidate) => candidate.provider === preferredProvider
      );
      if (preferredProviderCandidate) {
        return preferredProviderCandidate.releaseDate;
      }
    }
    return latestReleaseDateByName.get(unprefixedName);
  };
}
function getNextModelSelectorTab(current) {
  const currentIndex = MODEL_SELECTOR_TABS.findIndex((tab) => tab.id === current);
  const nextIndex = currentIndex < 0 ? 0 : (currentIndex + 1) % MODEL_SELECTOR_TABS.length;
  return MODEL_SELECTOR_TABS[nextIndex]?.id ?? "all-models";
}
function getPreviousModelSelectorTab(current) {
  const currentIndex = MODEL_SELECTOR_TABS.findIndex((tab) => tab.id === current);
  const previousIndex = currentIndex < 0 ? 0 : (currentIndex - 1 + MODEL_SELECTOR_TABS.length) % MODEL_SELECTOR_TABS.length;
  return MODEL_SELECTOR_TABS[previousIndex]?.id ?? "all-models";
}
function compareModelOptionsForDisplay(left, right) {
  const byRecency = compareModelsLatestFirst(left, right);
  if (byRecency !== 0) {
    return byRecency;
  }
  const byProvider = PROVIDER_COLLATOR.compare(left.provider, right.provider);
  if (byProvider !== 0) {
    return byProvider;
  }
  return 0;
}
function toModelIdentityKey(model) {
  return toCanonicalModelPickerKey({
    provider: model.provider,
    model: model.name,
    ...model.baseURL ? { baseURL: model.baseURL } : {}
  });
}
function normalizeLineText(value) {
  return stripUnsafeCharacters(value).replace(/\r?\n/g, " ").replace(/\s+/g, " ").trim();
}
function formatLineToWidth(value, width) {
  if (width <= 0) return "";
  const normalized = normalizeLineText(value);
  if (!normalized) {
    return " ".repeat(width);
  }
  const normalizedWidth = getCachedStringWidth(normalized);
  if (normalizedWidth <= width) {
    return normalized + " ".repeat(width - normalizedWidth);
  }
  if (width === 1) {
    return "\u2026";
  }
  const ellipsis = "\u2026";
  const targetWidth = width - getCachedStringWidth(ellipsis);
  let truncated = "";
  for (const char of toCodePoints(normalized)) {
    const candidate = `${truncated}${char}`;
    if (getCachedStringWidth(candidate) > targetWidth) {
      break;
    }
    truncated = candidate;
  }
  const withEllipsis = `${truncated}${ellipsis}`;
  const finalWidth = getCachedStringWidth(withEllipsis);
  if (finalWidth >= width) {
    return withEllipsis;
  }
  return withEllipsis + " ".repeat(width - finalWidth);
}
function isAddCustomOption(item) {
  return "type" in item && item.type === "add-custom";
}
function isModelOption(item) {
  return !("type" in item);
}
function getRowPrefix({
  isSelected,
  isDefault,
  isCurrent,
  isCustom,
  isFavorite
}) {
  return `${isSelected ? "\u203A" : " "} ${isDefault ? "\u2713" : " "} ${isCurrent ? "\u25CF" : " "} ${isFavorite ? "\u2605" : isCustom ? "\u25C7" : " "}`;
}
const REASONING_VARIANT_DESCRIPTIONS = {
  disabled: "Disable reasoning (fastest)",
  none: "Disable reasoning (fastest)",
  enabled: "Enable provider default reasoning",
  minimal: "Minimal reasoning",
  low: "Light reasoning, faster responses",
  medium: "Balanced reasoning",
  high: "Thorough reasoning",
  max: "Maximum reasoning within provider limits",
  xhigh: "Extra high reasoning"
};
function buildReasoningVariantOptions(support) {
  return support.variants.map((variant) => ({
    value: variant.id,
    label: variant.id === support.defaultVariant ? `${variant.label} (Recommended)` : variant.label,
    description: REASONING_VARIANT_DESCRIPTIONS[variant.id] ?? "Model/provider-native reasoning variant"
  }));
}
function getInitialVariantIndex(savedVariant, options, defaultVariant) {
  const preferredVariant = savedVariant ?? defaultVariant;
  if (!preferredVariant) return 0;
  const idx = options.findIndex((option) => option.value === preferredVariant);
  return idx >= 0 ? idx : 0;
}
const ModelSelector = forwardRef(function ModelSelector2({
  isVisible,
  onSelectModel,
  onSetDefaultModel,
  onClose,
  onAddCustomModel,
  onEditCustomModel,
  agent
}, ref) {
  const { rows: terminalRows, columns: terminalColumns } = useTerminalSize();
  const overlayWidth = useMemo(() => Math.max(20, terminalColumns - 2), [terminalColumns]);
  const maxVisibleItems = useMemo(() => {
    return getMaxVisibleItemsForTerminalRows({
      rows: terminalRows,
      hardCap: 8,
      reservedRows: 14
    });
  }, [terminalRows]);
  const [models, setModels] = useState([]);
  const [customModels, setCustomModels] = useState([]);
  const [modelPickerState, setModelPickerState] = useState(null);
  const [activeTab, setActiveTab] = useState("all-models");
  const [isLoading, setIsLoading] = useState(false);
  const [selection, setSelection] = useState({ index: 0, offset: 0 });
  const [searchQuery, setSearchQuery] = useState("");
  const [customModelAction, setCustomModelAction] = useState(null);
  const [pendingDeleteConfirm, setPendingDeleteConfirm] = useState(false);
  const selectedIndexRef = useRef(0);
  const deleteTimeoutRef = useRef(null);
  const maxVisibleItemsRef = useRef(maxVisibleItems);
  const [pendingReasoningModel, setPendingReasoningModel] = useState(null);
  const [reasoningVariantIndex, setReasoningVariantIndex] = useState(0);
  const [isSettingDefault, setIsSettingDefault] = useState(false);
  const [refreshVersion, setRefreshVersion] = useState(0);
  const reasoningVariantOptions = useMemo(() => {
    if (!pendingReasoningModel) return [];
    const support = getReasoningProfile(
      pendingReasoningModel.provider,
      pendingReasoningModel.name
    );
    return buildReasoningVariantOptions(support);
  }, [pendingReasoningModel]);
  selectedIndexRef.current = selection.index;
  maxVisibleItemsRef.current = maxVisibleItems;
  const modelsViewportItems = Math.max(1, maxVisibleItems - 1);
  useEffect(() => {
    return () => {
      if (deleteTimeoutRef.current) {
        clearTimeout(deleteTimeoutRef.current);
      }
    };
  }, []);
  useEffect(() => {
    if (!isVisible) return;
    let cancelled = false;
    setIsLoading(true);
    setModels([]);
    setCustomModels([]);
    setSearchQuery("");
    setSelection({ index: 0, offset: 0 });
    setCustomModelAction(null);
    setPendingDeleteConfirm(false);
    setPendingReasoningModel(null);
    setIsSettingDefault(false);
    setReasoningVariantIndex(0);
    setActiveTab("all-models");
    setModelPickerState(null);
    if (deleteTimeoutRef.current) {
      clearTimeout(deleteTimeoutRef.current);
      deleteTimeoutRef.current = null;
    }
    const fetchModels = async () => {
      try {
        try {
          const cacheInfo = getOpenRouterModelCacheInfo();
          if (cacheInfo.modelCount === 0) {
            await refreshOpenRouterModelCache({ force: true, timeoutMs: 1e4 });
          }
        } catch (error) {
          agent.logger.debug(
            `OpenRouter catalog refresh skipped: ${error instanceof Error ? error.message : String(error)}`
          );
        }
        const [
          allModels,
          providers,
          currentConfig,
          loadedCustomModels,
          preferences,
          codexModels
        ] = await Promise.all([
          Promise.resolve(agent.getSupportedModels()),
          Promise.resolve(agent.getSupportedProviders()),
          Promise.resolve(agent.getCurrentLLMConfig()),
          loadCustomModels(),
          loadGlobalPreferences().catch(() => null),
          loadChatGPTCodexModels(agent)
        ]);
        const pickerState = await loadModelPickerState().catch(() => null);
        const modelList = [];
        const defaultProvider = preferences?.llm.provider;
        const defaultModel = preferences?.llm.model;
        const defaultBaseURL = preferences?.llm.baseURL;
        const defaultReasoningVariant = preferences?.llm.reasoning?.variant;
        const resolveReleaseDate = createReleaseDateResolver({ allModels, providers });
        const defaultConfig = defaultProvider && defaultModel ? {
          provider: defaultProvider,
          model: defaultModel,
          ...defaultBaseURL ? { baseURL: defaultBaseURL } : {}
        } : null;
        const currentModelConfig = {
          provider: currentConfig.provider,
          model: currentConfig.model,
          ...currentConfig.baseURL ? { baseURL: currentConfig.baseURL } : {}
        };
        const getMatchState = (candidate) => ({
          isDefault: defaultConfig ? matchesConfiguredModel(candidate, defaultConfig) : false,
          isCurrent: matchesConfiguredModel(candidate, currentModelConfig)
        });
        const addChatGPTCodexModel = (input) => {
          const existing = modelList.find(
            (candidate) => candidate.provider === "openai-compatible" && candidate.name === input.model && candidate.baseURL === CODEX_CHATGPT_BASE_URL
          );
          if (existing) {
            existing.isDefault = existing.isDefault || input.isDefault;
            existing.isCurrent = existing.isCurrent || input.isCurrent;
            if (existing.displayName === void 0 && input.displayName !== void 0) {
              existing.displayName = input.displayName;
            }
            if (existing.releaseDate === void 0 && input.releaseDate !== void 0) {
              existing.releaseDate = input.releaseDate;
            }
            if (existing.reasoningVariant === void 0 && input.reasoningVariant !== void 0) {
              existing.reasoningVariant = input.reasoningVariant;
            }
            return;
          }
          modelList.push({
            provider: "openai-compatible",
            name: input.model,
            displayName: input.displayName,
            maxInputTokens: 128e3,
            isDefault: input.isDefault,
            isCurrent: input.isCurrent,
            isCustom: false,
            baseURL: CODEX_CHATGPT_BASE_URL,
            ...input.releaseDate !== void 0 ? { releaseDate: input.releaseDate } : {},
            ...input.reasoningVariant !== void 0 ? { reasoningVariant: input.reasoningVariant } : {}
          });
        };
        let ollamaModels = [];
        let localModels = [];
        try {
          ollamaModels = await listOllamaModels(DEFAULT_OLLAMA_URL);
        } catch (error) {
          agent.logger.debug("Ollama not available for model listing");
        }
        try {
          localModels = await getAllInstalledModels();
        } catch (error) {
          agent.logger.debug("Local models not available for listing");
        }
        for (const custom of loadedCustomModels) {
          const customProvider = custom.provider;
          const candidate = createModelIdentity({
            provider: customProvider,
            name: custom.name,
            baseURL: custom.baseURL
          });
          const { isDefault, isCurrent } = getMatchState(candidate);
          const modelOption = {
            provider: customProvider,
            name: custom.name,
            displayName: custom.displayName || custom.name,
            maxInputTokens: custom.maxInputTokens ?? 128e3,
            isDefault,
            isCurrent,
            isCustom: true
          };
          if (custom.baseURL) {
            modelOption.baseURL = custom.baseURL;
          }
          if (custom.reasoning?.variant) {
            modelOption.reasoningVariant = custom.reasoning.variant;
          }
          modelList.push(modelOption);
        }
        for (const provider of providers) {
          if (provider === "openai-compatible" || provider === "litellm" || provider === "glama" || provider === "bedrock")
            continue;
          if (provider === "ollama" || provider === "local" || provider === "vertex") {
            continue;
          }
          if (provider === "dexto-nova" && !isDextoAuthEnabled()) {
            continue;
          }
          const providerModels = [...allModels[provider]].sort(compareModelsLatestFirst);
          for (const model of providerModels) {
            if (isDeprecatedModelStatus(model.status)) {
              continue;
            }
            const releaseDate = resolveReleaseDate(
              provider,
              model.name,
              model.releaseDate
            );
            const originalProvider = "originalProvider" in model ? model.originalProvider : void 0;
            const candidate = createModelIdentity({
              provider,
              name: model.name
            });
            const { isDefault, isCurrent } = getMatchState(candidate);
            modelList.push({
              provider,
              name: model.name,
              displayName: model.displayName,
              maxInputTokens: model.maxInputTokens,
              isDefault,
              isCurrent,
              isCustom: false,
              ...releaseDate !== void 0 ? { releaseDate } : {},
              ...model.status !== void 0 ? { status: model.status } : {},
              ...defaultReasoningVariant && isDefault ? { reasoningVariant: defaultReasoningVariant } : {},
              // Store original provider for display purposes
              ...originalProvider && { originalProvider }
            });
          }
        }
        for (const codexModel of codexModels) {
          const candidate = {
            provider: "openai-compatible",
            name: codexModel.model,
            baseURL: CODEX_CHATGPT_BASE_URL
          };
          const isDefault = defaultConfig ? matchesConfiguredModel(candidate, defaultConfig) : false;
          const releaseDate = resolveReleaseDate("openai", codexModel.model) ?? resolveReleaseDate("openrouter", codexModel.model);
          addChatGPTCodexModel({
            model: codexModel.model,
            displayName: codexModel.displayName,
            isDefault,
            isCurrent: matchesConfiguredModel(candidate, currentModelConfig),
            ...releaseDate !== void 0 ? { releaseDate } : {},
            ...isDefault && defaultReasoningVariant ? { reasoningVariant: defaultReasoningVariant } : {}
          });
        }
        const addMissingConfiguredCodexModel = (configured) => {
          if (!configured || !isChatGPTCodexConfig(configured.provider, configured.baseURL)) {
            return;
          }
          const releaseDate = resolveReleaseDate("openai", configured.model) ?? resolveReleaseDate("openrouter", configured.model);
          addChatGPTCodexModel({
            model: configured.model,
            displayName: getModelDisplayName(configured.model, "openai"),
            isDefault: defaultConfig ? matchesConfiguredModel(
              {
                provider: "openai-compatible",
                name: configured.model,
                baseURL: CODEX_CHATGPT_BASE_URL
              },
              defaultConfig
            ) : false,
            isCurrent: matchesConfiguredModel(
              {
                provider: "openai-compatible",
                name: configured.model,
                baseURL: CODEX_CHATGPT_BASE_URL
              },
              currentModelConfig
            ),
            ...releaseDate !== void 0 ? { releaseDate } : {},
            ...defaultConfig && defaultReasoningVariant && matchesConfiguredModel(
              {
                provider: "openai-compatible",
                name: configured.model,
                baseURL: CODEX_CHATGPT_BASE_URL
              },
              defaultConfig
            ) ? { reasoningVariant: defaultReasoningVariant } : {}
          });
        };
        addMissingConfiguredCodexModel(defaultConfig);
        addMissingConfiguredCodexModel(currentModelConfig);
        for (const ollamaModel of ollamaModels) {
          const candidate = createModelIdentity({
            provider: "ollama",
            name: ollamaModel.name
          });
          const { isDefault, isCurrent } = getMatchState(candidate);
          modelList.push({
            provider: "ollama",
            name: ollamaModel.name,
            displayName: ollamaModel.name,
            maxInputTokens: 128e3,
            // Default, actual varies by model
            isDefault,
            isCurrent,
            isCustom: false
          });
        }
        for (const localModel of localModels) {
          const modelInfo = getLocalModelById(localModel.id);
          const displayName = modelInfo?.name || localModel.id;
          const maxInputTokens = modelInfo?.contextLength || 128e3;
          const candidate = createModelIdentity({
            provider: "local",
            name: localModel.id
          });
          const { isDefault, isCurrent } = getMatchState(candidate);
          modelList.push({
            provider: "local",
            name: localModel.id,
            displayName,
            maxInputTokens,
            isDefault,
            isCurrent,
            isCustom: false
          });
        }
        const vertexModels = allModels["vertex"];
        if (vertexModels) {
          for (const model of [...vertexModels].sort(compareModelsLatestFirst)) {
            if (isDeprecatedModelStatus(model.status)) {
              continue;
            }
            const releaseDate = resolveReleaseDate(
              "vertex",
              model.name,
              model.releaseDate
            );
            const candidate = createModelIdentity({
              provider: "vertex",
              name: model.name
            });
            const { isDefault, isCurrent } = getMatchState(candidate);
            modelList.push({
              provider: "vertex",
              name: model.name,
              displayName: model.displayName,
              maxInputTokens: model.maxInputTokens,
              isDefault,
              isCurrent,
              isCustom: false,
              ...releaseDate !== void 0 ? { releaseDate } : {},
              ...model.status !== void 0 ? { status: model.status } : {},
              ...defaultReasoningVariant && isDefault ? { reasoningVariant: defaultReasoningVariant } : {}
            });
          }
        }
        if (!cancelled) {
          const dedupedByKey = /* @__PURE__ */ new Map();
          const dedupeOrder = [];
          for (const model of modelList) {
            const key = toModelIdentityKey(model);
            const existing = dedupedByKey.get(key);
            if (!existing) {
              dedupedByKey.set(key, model);
              dedupeOrder.push(key);
              continue;
            }
            const preferred = model.isCustom && !existing.isCustom ? model : existing;
            const secondary = preferred === existing ? model : existing;
            const mergedBaseURL = preferred.baseURL ?? secondary.baseURL;
            const mergedReasoningVariant = preferred.reasoningVariant ?? secondary.reasoningVariant;
            const mergedOriginalProvider = preferred.originalProvider ?? secondary.originalProvider;
            const mergedReleaseDate = preferred.releaseDate ?? secondary.releaseDate;
            const mergedStatus = preferred.status ?? secondary.status;
            const mergedModel = {
              ...preferred,
              isDefault: preferred.isDefault || secondary.isDefault,
              isCurrent: preferred.isCurrent || secondary.isCurrent,
              displayName: preferred.displayName ?? secondary.displayName,
              maxInputTokens: Math.max(
                preferred.maxInputTokens,
                secondary.maxInputTokens
              )
            };
            if (mergedBaseURL !== void 0) {
              mergedModel.baseURL = mergedBaseURL;
            }
            if (mergedReasoningVariant !== void 0) {
              mergedModel.reasoningVariant = mergedReasoningVariant;
            }
            if (mergedOriginalProvider !== void 0) {
              mergedModel.originalProvider = mergedOriginalProvider;
            }
            if (mergedReleaseDate !== void 0) {
              mergedModel.releaseDate = mergedReleaseDate;
            }
            if (mergedStatus !== void 0) {
              mergedModel.status = mergedStatus;
            }
            dedupedByKey.set(key, mergedModel);
          }
          const dedupedModelList = dedupeOrder.map((key) => dedupedByKey.get(key)).filter((model) => model !== void 0);
          setModels(dedupedModelList);
          setCustomModels(loadedCustomModels);
          setModelPickerState(pickerState);
          setIsLoading(false);
          const currentIndex = dedupedModelList.findIndex((m) => m.isCurrent);
          if (currentIndex >= 0) {
            const nextIndex = currentIndex;
            const nextMaxVisibleItems = maxVisibleItemsRef.current;
            const maxOffset = Math.max(
              0,
              dedupedModelList.length - nextMaxVisibleItems
            );
            const nextOffset = Math.min(
              maxOffset,
              Math.max(0, currentIndex - nextMaxVisibleItems + 1)
            );
            selectedIndexRef.current = nextIndex;
            setSelection({ index: nextIndex, offset: nextOffset });
          }
        }
      } catch (error) {
        if (!cancelled) {
          agent.logger.error(
            `Failed to fetch models: ${error instanceof Error ? error.message : "Unknown error"}`
          );
          setModels([]);
          setModelPickerState(null);
          setIsLoading(false);
        }
      }
    };
    void fetchModels();
    return () => {
      cancelled = true;
    };
  }, [isVisible, agent, refreshVersion]);
  const favoriteKeySet = useMemo(
    () => new Set(
      (modelPickerState?.favorites ?? []).map((entry) => toCanonicalModelPickerKey(entry))
    ),
    [modelPickerState]
  );
  const matchesSearch = useCallback(
    (model) => {
      if (!searchQuery.trim()) {
        return true;
      }
      const query = searchQuery.toLowerCase().replace(/[\s-]+/g, "");
      const name = model.name.toLowerCase().replace(/[\s-]+/g, "");
      const displayName = (model.displayName || "").toLowerCase().replace(/[\s-]+/g, "");
      const provider = model.provider.toLowerCase().replace(/[\s-]+/g, "");
      const providerDisplay = getLLMProviderDisplayName(model.provider, model.baseURL).toLowerCase().replace(/[\s-]+/g, "");
      return name.includes(query) || displayName.includes(query) || provider.includes(query) || providerDisplay.includes(query);
    },
    [searchQuery]
  );
  const filteredItems = useMemo(() => {
    const addCustomOption = { type: "add-custom" };
    const hasSearchQuery = searchQuery.trim().length > 0;
    const allCandidates = [...models].sort(compareModelOptionsForDisplay);
    const modelsByKey = new Map(
      allCandidates.map((model) => [toModelIdentityKey(model), model])
    );
    const toUniqueMatchingModels = (candidates, limit) => {
      const deduped = [];
      const seen = /* @__PURE__ */ new Set();
      for (const candidate of candidates) {
        if (!candidate || !matchesSearch(candidate)) {
          continue;
        }
        const key = toModelIdentityKey(candidate);
        if (seen.has(key)) {
          continue;
        }
        seen.add(key);
        deduped.push(candidate);
        if (limit !== void 0 && deduped.length >= limit) {
          break;
        }
      }
      return deduped;
    };
    const providersInModels = Array.from(
      new Set(models.map((model) => model.provider))
    );
    const featuredCandidates = getCuratedModelRefsForProviders({
      providers: providersInModels,
      max: FEATURED_SECTION_LIMIT
    }).map((ref2) => modelsByKey.get(toCanonicalModelPickerKey(ref2)));
    const recentsFromState = (modelPickerState?.recents ?? []).map(
      (entry) => modelsByKey.get(toCanonicalModelPickerKey(entry))
    );
    const favoritesFromState = (modelPickerState?.favorites ?? []).map(
      (entry) => modelsByKey.get(toCanonicalModelPickerKey(entry))
    );
    const customCandidates = allCandidates.filter((model) => model.isCustom);
    const tabModels = hasSearchQuery ? toUniqueMatchingModels(allCandidates) : activeTab === "all-models" ? toUniqueMatchingModels(allCandidates) : activeTab === "featured" ? toUniqueMatchingModels(featuredCandidates) : activeTab === "recents" ? toUniqueMatchingModels(recentsFromState) : activeTab === "favorites" ? toUniqueMatchingModels(favoritesFromState) : toUniqueMatchingModels(customCandidates);
    return activeTab === "custom" && !hasSearchQuery ? [addCustomOption, ...tabModels] : tabModels;
  }, [activeTab, matchesSearch, modelPickerState, models, searchQuery]);
  const hasAddCustomOption = activeTab === "custom" && searchQuery.trim().length === 0;
  const modelStartIndex = hasAddCustomOption ? 1 : 0;
  const listViewportItems = hasAddCustomOption ? modelsViewportItems : maxVisibleItems;
  useEffect(() => {
    setSelection((prev) => {
      const maxIndex = Math.max(0, filteredItems.length - 1);
      const nextIndex = Math.min(prev.index, maxIndex);
      let nextOffset = prev.offset;
      const nextModelsLength = Math.max(0, filteredItems.length - modelStartIndex);
      if (nextIndex >= modelStartIndex) {
        const modelIndex = nextIndex - modelStartIndex;
        if (modelIndex < nextOffset) {
          nextOffset = modelIndex;
        } else if (modelIndex >= nextOffset + listViewportItems) {
          nextOffset = Math.max(0, modelIndex - listViewportItems + 1);
        }
      } else {
        nextOffset = 0;
      }
      const maxOffset = Math.max(0, nextModelsLength - listViewportItems);
      nextOffset = Math.min(maxOffset, Math.max(0, nextOffset));
      if (nextIndex === prev.index && nextOffset === prev.offset) {
        return prev;
      }
      selectedIndexRef.current = nextIndex;
      return { index: nextIndex, offset: nextOffset };
    });
  }, [filteredItems.length, listViewportItems, modelStartIndex]);
  const handleDeleteCustomModel = useCallback(
    async (model) => {
      if (!model.isCustom) return;
      try {
        await deleteCustomModel(model.name);
        const updated = await loadCustomModels();
        setCustomModels(updated);
        setModels((prev) => prev.filter((m) => !(m.isCustom && m.name === model.name)));
      } catch (error) {
        agent.logger.error(
          `Failed to delete custom model: ${error instanceof Error ? error.message : "Unknown error"}`
        );
      }
    },
    [agent]
  );
  const handleToggleFavoriteModel = useCallback(
    async (model) => {
      try {
        const baseURL = canonicalizeModelBaseURL(model.baseURL);
        await toggleFavoriteModel({
          provider: model.provider,
          model: model.name,
          ...baseURL ? { baseURL } : {}
        });
        const nextState = await loadModelPickerState();
        setModelPickerState(nextState);
      } catch (error) {
        agent.logger.error(
          `Failed to toggle favorite model: ${error instanceof Error ? error.message : "Unknown error"}`
        );
      }
    },
    [agent]
  );
  const clearActionState = () => {
    setCustomModelAction(null);
    setPendingDeleteConfirm(false);
    if (deleteTimeoutRef.current) {
      clearTimeout(deleteTimeoutRef.current);
      deleteTimeoutRef.current = null;
    }
  };
  const beginReasoningVariantSelection = (item, settingDefault) => {
    const support = getReasoningProfile(item.provider, item.name);
    if (!support.capable) {
      return false;
    }
    const options = buildReasoningVariantOptions(support);
    setPendingReasoningModel(item);
    setIsSettingDefault(settingDefault);
    setReasoningVariantIndex(
      getInitialVariantIndex(item.reasoningVariant, options, support.defaultVariant)
    );
    return true;
  };
  useImperativeHandle(
    ref,
    () => ({
      handleInput: (input, key) => {
        if (!isVisible) return false;
        if (isLoading) {
          if (key.escape) {
            onClose();
          }
          return true;
        }
        if (pendingReasoningModel) {
          if (key.escape) {
            setPendingReasoningModel(null);
            setIsSettingDefault(false);
            return true;
          }
          if (key.upArrow) {
            if (reasoningVariantOptions.length === 0) return true;
            setReasoningVariantIndex(
              (prev) => prev > 0 ? prev - 1 : reasoningVariantOptions.length - 1
            );
            return true;
          }
          if (key.downArrow) {
            if (reasoningVariantOptions.length === 0) return true;
            setReasoningVariantIndex(
              (prev) => prev < reasoningVariantOptions.length - 1 ? prev + 1 : 0
            );
            return true;
          }
          if (key.return) {
            const selectedOption = reasoningVariantOptions[reasoningVariantIndex] ?? reasoningVariantOptions[0];
            const reasoningVariant = selectedOption?.value;
            if (!reasoningVariant) {
              setPendingReasoningModel(null);
              setIsSettingDefault(false);
              return true;
            }
            if (isSettingDefault) {
              clearActionState();
              void (async () => {
                await onSetDefaultModel(
                  pendingReasoningModel.provider,
                  pendingReasoningModel.name,
                  pendingReasoningModel.displayName,
                  pendingReasoningModel.baseURL,
                  reasoningVariant
                );
                setRefreshVersion((prev) => prev + 1);
                onClose();
              })();
            } else {
              onSelectModel(
                pendingReasoningModel.provider,
                pendingReasoningModel.name,
                pendingReasoningModel.displayName,
                pendingReasoningModel.baseURL,
                reasoningVariant
              );
            }
            setPendingReasoningModel(null);
            setIsSettingDefault(false);
            return true;
          }
          return true;
        }
        if (key.escape) {
          if (customModelAction) {
            clearActionState();
            return true;
          }
          onClose();
          return true;
        }
        const itemsLength = filteredItems.length;
        const currentItem = filteredItems[selectedIndexRef.current];
        const selectedModel = currentItem && isModelOption(currentItem) ? currentItem : null;
        const isCustomActionItem = selectedModel?.isCustom ?? false;
        const isSelectableItem = selectedModel !== null;
        if (key.tab) {
          clearActionState();
          setActiveTab((prev) => getNextModelSelectorTab(prev));
          selectedIndexRef.current = 0;
          setSelection({ index: 0, offset: 0 });
          return true;
        }
        if (key.ctrl && input === "f" && isSelectableItem) {
          const item = selectedModel;
          if (!item) return true;
          clearActionState();
          void handleToggleFavoriteModel(item);
          return true;
        }
        if (key.ctrl && key.rightArrow) {
          if (!isSelectableItem) return false;
          if (customModelAction === null) {
            setCustomModelAction("favorite");
            return true;
          }
          if (customModelAction === "favorite") {
            setCustomModelAction("default");
            return true;
          }
          if (customModelAction === "default") {
            if (isCustomActionItem) {
              setCustomModelAction("edit");
              return true;
            }
            return true;
          }
          if (customModelAction === "edit") {
            if (isCustomActionItem) {
              setCustomModelAction("delete");
              setPendingDeleteConfirm(false);
            }
            return true;
          }
          if (customModelAction === "delete") {
            return true;
          }
        }
        if (key.ctrl && key.leftArrow) {
          if (customModelAction === "delete") {
            setCustomModelAction("edit");
            setPendingDeleteConfirm(false);
            if (deleteTimeoutRef.current) {
              clearTimeout(deleteTimeoutRef.current);
              deleteTimeoutRef.current = null;
            }
            return true;
          }
          if (customModelAction === "default") {
            setCustomModelAction("favorite");
            return true;
          }
          if (customModelAction === "edit") {
            setCustomModelAction("default");
            return true;
          }
          if (customModelAction === "favorite") {
            setCustomModelAction(null);
            return true;
          }
          return false;
        }
        if (key.rightArrow) {
          clearActionState();
          setActiveTab((prev) => getNextModelSelectorTab(prev));
          selectedIndexRef.current = 0;
          setSelection({ index: 0, offset: 0 });
          return true;
        }
        if (key.leftArrow) {
          clearActionState();
          setActiveTab((prev) => getPreviousModelSelectorTab(prev));
          selectedIndexRef.current = 0;
          setSelection({ index: 0, offset: 0 });
          return true;
        }
        if (input && !key.return && !key.upArrow && !key.downArrow && !key.tab) {
          if (customModelAction) {
            clearActionState();
          }
          if (key.backspace || key.delete) {
            setSearchQuery((prev) => prev.slice(0, -1));
            return true;
          }
          if (input.length === 1 && input.charCodeAt(0) >= 32) {
            setSearchQuery((prev) => prev + input);
            selectedIndexRef.current = 0;
            setSelection({ index: 0, offset: 0 });
            return true;
          }
        }
        if (key.backspace || key.delete) {
          setSearchQuery((prev) => prev.slice(0, -1));
          return true;
        }
        if (itemsLength === 0) return false;
        if (key.upArrow) {
          if (customModelAction) {
            clearActionState();
          }
          const nextIndex = (selectedIndexRef.current - 1 + itemsLength) % itemsLength;
          selectedIndexRef.current = nextIndex;
          setSelection((prev) => {
            let nextOffset = prev.offset;
            const nextModelsLength = Math.max(0, itemsLength - modelStartIndex);
            if (nextIndex >= modelStartIndex) {
              const modelIndex = nextIndex - modelStartIndex;
              if (modelIndex < prev.offset) {
                nextOffset = modelIndex;
              } else if (modelIndex >= prev.offset + listViewportItems) {
                nextOffset = Math.max(0, modelIndex - listViewportItems + 1);
              }
            } else {
              nextOffset = 0;
            }
            const maxOffset = Math.max(0, nextModelsLength - listViewportItems);
            nextOffset = Math.min(maxOffset, Math.max(0, nextOffset));
            return { index: nextIndex, offset: nextOffset };
          });
          return true;
        }
        if (key.downArrow) {
          if (customModelAction) {
            clearActionState();
          }
          const nextIndex = (selectedIndexRef.current + 1) % itemsLength;
          selectedIndexRef.current = nextIndex;
          setSelection((prev) => {
            let nextOffset = prev.offset;
            const nextModelsLength = Math.max(0, itemsLength - modelStartIndex);
            if (nextIndex >= modelStartIndex) {
              const modelIndex = nextIndex - modelStartIndex;
              if (modelIndex < prev.offset) {
                nextOffset = modelIndex;
              } else if (modelIndex >= prev.offset + listViewportItems) {
                nextOffset = Math.max(0, modelIndex - listViewportItems + 1);
              }
            } else {
              nextOffset = 0;
            }
            const maxOffset = Math.max(0, nextModelsLength - listViewportItems);
            nextOffset = Math.min(maxOffset, Math.max(0, nextOffset));
            return { index: nextIndex, offset: nextOffset };
          });
          return true;
        }
        if (key.return && itemsLength > 0) {
          const item = filteredItems[selectedIndexRef.current];
          if (item) {
            if (isAddCustomOption(item)) {
              onAddCustomModel();
              return true;
            }
            if (customModelAction === "favorite") {
              void handleToggleFavoriteModel(item);
              return true;
            }
            if (customModelAction === "edit" && item.isCustom) {
              const customModel = customModels.find(
                (cm) => cm.name === item.name && (cm.provider ?? "openai-compatible") === item.provider
              );
              if (customModel) {
                onEditCustomModel(customModel);
              }
              return true;
            }
            if (customModelAction === "default") {
              if (beginReasoningVariantSelection(item, true)) {
                return true;
              }
              clearActionState();
              void (async () => {
                await onSetDefaultModel(
                  item.provider,
                  item.name,
                  item.displayName,
                  item.baseURL,
                  item.reasoningVariant
                );
                setRefreshVersion((prev) => prev + 1);
                onClose();
              })();
              return true;
            }
            if (customModelAction === "delete" && item.isCustom) {
              if (pendingDeleteConfirm) {
                clearActionState();
                void handleDeleteCustomModel(item);
              } else {
                setPendingDeleteConfirm(true);
                if (deleteTimeoutRef.current) {
                  clearTimeout(deleteTimeoutRef.current);
                }
                deleteTimeoutRef.current = setTimeout(() => {
                  setPendingDeleteConfirm(false);
                  deleteTimeoutRef.current = null;
                }, 3e3);
              }
              return true;
            }
            if (beginReasoningVariantSelection(item, false)) {
              return true;
            }
            onSelectModel(item.provider, item.name, item.displayName, item.baseURL);
            return true;
          }
        }
        return false;
      }
    }),
    [
      isVisible,
      isLoading,
      filteredItems,
      maxVisibleItems,
      listViewportItems,
      modelStartIndex,
      onClose,
      onSelectModel,
      onSetDefaultModel,
      onAddCustomModel,
      onEditCustomModel,
      customModelAction,
      pendingDeleteConfirm,
      customModels,
      handleDeleteCustomModel,
      handleToggleFavoriteModel,
      pendingReasoningModel,
      reasoningVariantIndex,
      reasoningVariantOptions,
      isSettingDefault,
      activeTab,
      agent,
      beginReasoningVariantSelection
    ]
  );
  if (!isVisible) return null;
  const blankLine = " ".repeat(overlayWidth);
  if (pendingReasoningModel) {
    const totalOptions = reasoningVariantOptions.length;
    const reasoningVisibleItems = Math.min(maxVisibleItems, totalOptions);
    const reasoningOffset = Math.min(
      Math.max(0, reasoningVariantIndex - reasoningVisibleItems + 1),
      Math.max(0, totalOptions - reasoningVisibleItems)
    );
    const visibleReasoningOptions = reasoningVariantOptions.slice(
      reasoningOffset,
      reasoningOffset + reasoningVisibleItems
    );
    const selectedReasoningOption = reasoningVariantOptions[reasoningVariantIndex] ?? reasoningVariantOptions[0];
    return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: overlayWidth, children: [
      /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, children: /* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
        "Reasoning Variant",
        isSettingDefault ? /* @__PURE__ */ jsx(Text, { color: "gray", children: " (default)" }) : null
      ] }) }),
      /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: formatLineToWidth(
        pendingReasoningModel.displayName || pendingReasoningModel.name,
        overlayWidth
      ) }) }),
      /* @__PURE__ */ jsx(
        Box,
        {
          flexDirection: "column",
          height: maxVisibleItems,
          marginTop: 1,
          width: overlayWidth,
          children: Array.from({ length: maxVisibleItems }, (_, rowIndex) => {
            const option = visibleReasoningOptions[rowIndex];
            if (!option) {
              return /* @__PURE__ */ jsx(
                Box,
                {
                  paddingX: 0,
                  paddingY: 0,
                  width: overlayWidth,
                  children: /* @__PURE__ */ jsx(Text, { children: blankLine })
                },
                `reasoning-empty-${rowIndex}`
              );
            }
            const actualIndex = reasoningOffset + rowIndex;
            const isSelected = actualIndex === reasoningVariantIndex;
            return /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, children: /* @__PURE__ */ jsx(Text, { color: isSelected ? "cyan" : "gray", bold: isSelected, children: formatLineToWidth(
              `${isSelected ? "\u203A" : " "} ${option.label}`,
              overlayWidth
            ) }) }, option.value);
          })
        }
      ),
      /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, marginTop: 1, width: overlayWidth, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: formatLineToWidth(
        selectedReasoningOption?.description ?? "",
        overlayWidth
      ) }) }),
      /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, children: /* @__PURE__ */ jsx(HintBar, { hints: ["\u2191\u2193 navigate", "Enter select", "Esc back"] }) })
    ] });
  }
  const selectedIndex = selection.index;
  const scrollOffset = selection.offset;
  const listItems = filteredItems.filter((item) => !isAddCustomOption(item));
  const visibleItems = listItems.slice(scrollOffset, scrollOffset + listViewportItems);
  const selectedItem = filteredItems[selectedIndex];
  const hasActionableItems = Boolean(selectedItem && isModelOption(selectedItem));
  const searchLine = formatLineToWidth(
    `Search: ${searchQuery || "Type to filter models\u2026"}`,
    overlayWidth
  );
  const addCustomLine = hasAddCustomOption ? formatLineToWidth(
    `${getRowPrefix({
      isSelected: selectedIndex === 0,
      isDefault: false,
      isCurrent: false,
      isCustom: false,
      isFavorite: false
    })} Add custom model\u2026`,
    overlayWidth
  ) : "";
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: overlayWidth, children: [
    /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, children: /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "Models" }) }),
    /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, flexDirection: "row", children: MODEL_SELECTOR_TABS.map((tab) => /* @__PURE__ */ jsx(
      Box,
      {
        marginRight: 1,
        borderStyle: "round",
        borderColor: activeTab === tab.id ? "cyan" : "gray",
        paddingX: 1,
        children: /* @__PURE__ */ jsx(
          Text,
          {
            color: activeTab === tab.id ? "cyan" : "gray",
            bold: activeTab === tab.id,
            children: tab.label
          }
        )
      },
      tab.id
    )) }),
    /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, children: /* @__PURE__ */ jsx(Text, { color: searchQuery ? "white" : "gray", children: searchLine }) }),
    /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, width: overlayWidth, children: [
      hasAddCustomOption && /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, width: overlayWidth, children: /* @__PURE__ */ jsx(
        Text,
        {
          color: selectedIndex === 0 ? "green" : "gray",
          bold: selectedIndex === 0,
          children: addCustomLine
        }
      ) }),
      /* @__PURE__ */ jsx(Box, { flexDirection: "column", height: listViewportItems, width: overlayWidth, children: isLoading || listItems.length === 0 ? Array.from({ length: listViewportItems }, (_, index) => /* @__PURE__ */ jsx(
        Box,
        {
          paddingX: 0,
          paddingY: 0,
          width: overlayWidth,
          children: /* @__PURE__ */ jsx(Text, { children: blankLine })
        },
        `model-empty-${index}`
      )) : Array.from({ length: listViewportItems }, (_, rowIndex) => {
        const item = visibleItems[rowIndex];
        if (!item) {
          return /* @__PURE__ */ jsx(
            Box,
            {
              paddingX: 0,
              paddingY: 0,
              width: overlayWidth,
              children: /* @__PURE__ */ jsx(Text, { children: blankLine })
            },
            `model-empty-${rowIndex}`
          );
        }
        const actualIndex = modelStartIndex + scrollOffset + rowIndex;
        const isSelected = actualIndex === selectedIndex;
        const providerDisplay = getLLMProviderDisplayName(
          item.provider,
          item.baseURL
        );
        const name = item.displayName || item.name;
        const isFavorite = favoriteKeySet.has(
          toCanonicalModelPickerKey({
            provider: item.provider,
            model: item.name,
            ...item.baseURL ? { baseURL: item.baseURL } : {}
          })
        );
        const prefix = getRowPrefix({
          isSelected,
          isDefault: item.isDefault,
          isCurrent: item.isCurrent,
          isCustom: item.isCustom,
          isFavorite
        });
        return /* @__PURE__ */ jsx(
          Box,
          {
            flexDirection: "row",
            paddingX: 0,
            paddingY: 0,
            width: overlayWidth,
            children: /* @__PURE__ */ jsx(Text, { color: isSelected ? "cyan" : "gray", bold: isSelected, children: formatLineToWidth(
              `${prefix} ${name} (${providerDisplay})`,
              overlayWidth
            ) })
          },
          `model-${activeTab}-${actualIndex}-${toModelIdentityKey(item)}`
        );
      }) })
    ] }),
    /* @__PURE__ */ jsx(Box, { paddingX: 0, paddingY: 0, marginTop: 1, width: overlayWidth, children: /* @__PURE__ */ jsx(
      HintBar,
      {
        hints: [
          "\u2191\u2193 navigate",
          "Enter select/apply",
          "Esc close",
          "\u2190\u2192 switch tab",
          hasActionableItems ? "Ctrl+F quick favorite" : ""
        ]
      }
    ) })
  ] });
});
var ModelSelectorRefactored_default = ModelSelector;
export {
  ModelSelectorRefactored_default as default
};
