"use client"; import { ExternalLink } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { getModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2Get, getModelConfigurationV2DefaultsApiV1OrganizationsModelConfigurationsV2DefaultsGet, saveModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2Put, } from "@/client/sdk.gen"; import type { ModelConfigurationPricingResponse, OrganizationAiModelConfigurationResponse, OrganizationAiModelConfigurationV2, } from "@/client/types.gen"; import { AIModelConfigurationV2Editor, type ModelConfigurationDefaultsV2 } from "@/components/AIModelConfigurationV2Editor"; import { Skeleton } from "@/components/ui/skeleton"; import { useUserConfig } from "@/context/UserConfigContext"; import { detailFromError } from "@/lib/apiError"; import { useAuth } from "@/lib/auth"; import { fetchModelConfigurationPricing } from "@/lib/modelConfigurationPricing"; export default function ModelConfigurationV2({ docsUrl }: { docsUrl?: string }) { const auth = useAuth(); const { refreshConfig } = useUserConfig(); const hasFetched = useRef(false); const [defaults, setDefaults] = useState(null); const [response, setResponse] = useState(null); const [pricing, setPricing] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [notice, setNotice] = useState(null); useEffect(() => { if (auth.loading || !auth.user || hasFetched.current) return; hasFetched.current = true; const load = async () => { setLoading(true); setError(null); const [defaultsResult, configResult, pricingResult] = await Promise.all([ getModelConfigurationV2DefaultsApiV1OrganizationsModelConfigurationsV2DefaultsGet(), getModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2Get(), fetchModelConfigurationPricing(), ]); if (defaultsResult.error) { setError(detailFromError(defaultsResult.error, "Failed to load model configuration defaults")); setLoading(false); return; } if (configResult.error) { setError(detailFromError(configResult.error, "Failed to load model configuration")); setLoading(false); return; } const nextDefaults = defaultsResult.data as ModelConfigurationDefaultsV2; if (!nextDefaults || !configResult.data) { setError("Failed to load model configuration"); setLoading(false); return; } setDefaults(nextDefaults); setResponse(configResult.data); setPricing(pricingResult); setLoading(false); }; load(); }, [auth.loading, auth.user]); const saveConfiguration = async (configuration: OrganizationAiModelConfigurationV2) => { if (!defaults) return; setError(null); setNotice(null); const result = await saveModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2Put({ body: configuration, }); if (result.error) { throw new Error(detailFromError(result.error, "Failed to save model configuration")); } if (!result.data) { throw new Error("Failed to save model configuration"); } setResponse(result.data); void fetchModelConfigurationPricing().then(setPricing); await refreshConfig(); setNotice("Model configuration saved"); }; if (loading) { return (
); } return (

AI Models Configuration

Organization-scoped model settings.{" "} {docsUrl && ( Learn more )}

{error && (
{error}
)} {notice && (
{notice}
)} {defaults && response && ( )}
); }