import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; import { ComboboxSelect } from "@/components/ui/combobox"; import ModelParameters from "@/components/ui/custom/modelParameters"; import { Label } from "@/components/ui/label"; import { ModelMultiselect } from "@/components/ui/modelMultiselect"; import { Separator } from "@/components/ui/separator"; import { Skeleton } from "@/components/ui/skeleton"; import { getProviderLabel } from "@/lib/constants/logs"; import { useGetVirtualKeysQuery } from "@/lib/store"; import { useGetAllKeysQuery, useGetProvidersQuery } from "@/lib/store/apis/providersApi"; import { ModelProviderName } from "@/lib/types/config"; import { ModelParams } from "@/lib/types/prompts"; import { cn } from "@/lib/utils"; import { PromptDeploymentsAccordionItem } from "@enterprise/components/prompt-deployments/promptDeploymentsAccordionItem"; import { useCallback, useMemo, useState } from "react"; import { ApiKeySelectorView } from "../components/apiKeySelectorView"; import { VariablesTableView } from "../components/variablesTableView"; import { usePromptContext } from "../context"; export function SettingsPanel() { const { provider, setProvider, model, setModel: onModelChange, modelParams, setModelParams: onModelParamsChange, apiKeyId, setApiKeyId, variables, setVariables, selectedPromptId, } = usePromptContext(); const onProviderChange = useCallback( (p: string) => { setProvider(p); setApiKeyId("__auto__"); onModelChange(""); onModelParamsChange({} as ModelParams); }, [setProvider, setApiKeyId, onModelChange, onModelParamsChange], ); const onApiKeyIdChange = useCallback( (id: string) => { setApiKeyId(id); }, [setApiKeyId], ); // Dynamic providers const { data: providers, isLoading: isLoadingProviders } = useGetProvidersQuery(); const { data: virtualKeysData } = useGetVirtualKeysQuery(); // Keys for the API Key selector (from /api/keys endpoint, provider-filtered) const { data: allKeys, isSuccess: hasLoadedAllKeys } = useGetAllKeysQuery(); const isInitialLoading = isLoadingProviders; const configuredProviders = useMemo(() => { const activeVirtualKeys = virtualKeysData?.virtual_keys?.filter((vk) => vk.is_active) ?? []; if (!hasLoadedAllKeys) { return providers ?? []; } const keyedProviders = new Set((allKeys ?? []).map((k) => k.provider)); return (providers ?? []).filter((p) => { if (keyedProviders.has(p.name)) return true; // Include providers that have active virtual keys (wildcard or explicitly targeting this provider) return activeVirtualKeys.some( (vk) => !vk.provider_configs || vk.provider_configs.length === 0 || vk.provider_configs.some((pc) => pc.provider === p.name), ); }); }, [providers, virtualKeysData, allKeys, hasLoadedAllKeys]); // Ensure current provider always has a label-resolved option (even before providers query loads) const providerOptions = useMemo(() => { const opts = configuredProviders.map((p) => ({ label: getProviderLabel(p.name), value: p.name })); if (provider && !opts.find((o) => o.value === provider)) { opts.unshift({ label: getProviderLabel(provider), value: provider as ModelProviderName }); } return opts; }, [configuredProviders, provider]); const providerKeys = useMemo(() => (allKeys ?? []).filter((k) => k.provider === provider), [allKeys, provider]); // Virtual keys filtered by selected provider const providerVirtualKeys = useMemo(() => { const vks = virtualKeysData?.virtual_keys ?? []; return vks.filter((vk) => { if (!vk.is_active) return false; // No provider configs means all providers are allowed (wildcard) if (!vk.provider_configs || vk.provider_configs.length === 0) return true; // Check if selected provider is in the configured providers return vk.provider_configs.some((pc) => pc.provider === provider); }); }, [virtualKeysData, provider]); // Separate keys/vks to pass to model fetch for filtering. const filterKeys = useMemo(() => { const isProviderKey = providerKeys.some((k) => k.key_id === apiKeyId); if (isProviderKey) return [apiKeyId]; const isVirtualKey = providerVirtualKeys.some((vk) => vk.id === apiKeyId); if (isVirtualKey) return undefined; // Auto: pass all provider key IDs return providerKeys.map((k) => k.key_id); }, [apiKeyId, providerKeys, providerVirtualKeys]); const filterVks = useMemo(() => { const isVirtualKey = providerVirtualKeys.some((vk) => vk.id === apiKeyId); if (isVirtualKey) return [apiKeyId]; return undefined; }, [apiKeyId, providerVirtualKeys]); const handleModelParamsChange = useCallback( (params: Record) => { onModelParamsChange(params as ModelParams); }, [onModelParamsChange], ); const hasModel = Boolean(model); type SettingsSection = "parameters" | "deployments"; const [openSection, setOpenSection] = useState("parameters"); if (isInitialLoading) { return (
); } return (
{ if (v === "parameters" || v === "deployments") { setOpenSection(v); } else { setOpenSection(undefined); } }} className="flex min-h-0 flex-1 flex-col" > Configuration
v && onProviderChange(v)} placeholder="Select provider" hideClear />
0 ? filterKeys : undefined} vks={filterVks} value={model} onChange={(v) => onModelChange(v)} isSingleSelect placeholder={!provider ? "Select a provider first" : "Select model"} disabled={!provider} unfiltered={true} />
{(providerKeys.length > 0 || providerVirtualKeys.length > 0) && !!provider && ( onApiKeyIdChange(v ?? "__auto__")} disabled={!provider} /> )} {Object.keys(variables).length > 0 && ( <> )} {hasModel && ( <>
)}
{selectedPromptId && }
); }