import * as React from 'react'; import * as z from 'zod/v4'; import { Button, Chip, Typography } from '@mui/joy'; import { hasServerConf } from '~/common/app.serverconf'; import type { DModelsServiceId } from '~/common/stores/llms/llms.service.types'; import { AlreadySet } from '~/common/components/AlreadySet'; import { ExpanderControlledBox } from '~/common/components/ExpanderControlledBox'; import { ExternalLink } from '~/common/components/ExternalLink'; import { FormInputKey } from '~/common/components/forms/FormInputKey'; import { InlineError } from '~/common/components/InlineError'; import { isLocalUrl } from '~/common/util/urlUtils'; import { Link } from '~/common/components/Link'; import { LocalAIIcon } from '~/common/components/icons/vendors/LocalAIIcon'; import { SetupFormClientSideToggle } from '~/common/components/forms/SetupFormClientSideToggle'; import { SetupFormCorsHint } from '~/common/components/forms/SetupFormCorsHint'; import { SetupFormRefetchButton } from '~/common/components/forms/SetupFormRefetchButton'; import { ApproximateCosts } from '../ApproximateCosts'; import { useLlmUpdateModels } from '../../llm.client.hooks'; import { useServiceSetup } from '../useServiceSetup'; import { LocalAIAdmin } from './LocalAIAdmin'; import { ModelVendorLocalAI } from './localai.vendor'; const localAIHostSchema = z.url().startsWith('http'); export function LocalAIServiceSetup(props: { serviceId: DModelsServiceId }) { // state const [checkboxExpanded, setCheckboxExpanded] = React.useState(false); const [adminOpen, setAdminOpen] = React.useState(false); // external state const backendHasHost = hasServerConf('hasLlmLocalAIHost'); const backendHasKey = hasServerConf('hasLlmLocalAIKey'); const { service, serviceAccess, serviceHasLLMs, updateSettings } = useServiceSetup(props.serviceId, ModelVendorLocalAI); // derived state const { clientSideFetch, oaiHost: localAIHost, oaiKey: localAIKey } = serviceAccess; // host validation const userHostRequired = !backendHasHost; const userHostValid = localAIHost.length >= 6 && localAIHostSchema.safeParse(localAIHost).success; const userHostError = !!localAIHost && !userHostValid; const shallFetchSucceed = localAIHost ? userHostValid : backendHasHost; // fetch models - the OpenAI way const { isFetching, refetch, isError, error } = useLlmUpdateModels(!serviceHasLLMs && shallFetchSucceed, service); return <>
Please ensure your LocalAI instance is correctly configured. {checkboxExpanded && <> Visit the LocalAI website for detailed setup instructions.} setCheckboxExpanded(on => !on)}> Show {checkboxExpanded ? 'less' : 'more'} Supported features: ✅{' '}Text generation with GPTs
✅{' '}Function calling by GPTs
✅{' '}Model Gallery
✅{' '}Vision API for image chats
✅{' '}JSON output
✅{' '}Image generation (stablediffusion, dreamshaper, sd-3.5-large/medium-ggml)
✖️{' '}Speech transcription
✖️{' '}Text to speech
✖️{' '}Embeddings generation
✖️{' '}Voice cloning
: Learn more} value={localAIHost} onChange={value => updateSettings({ localAIHost: value })} /> updateSettings({ localAIKey: value })} /> updateSettings({ csf: on })} helpText='Fetch models and make requests directly from your LocalAI instance using the browser. Recommended for local setups - requires CORS enabled on the LocalAI server.' localHostDetected={isLocalUrl(localAIHost)} /> setAdminOpen(true)} startDecorator={}> Install Models } /> Make sure CORS is enabled on the LocalAI server. Start it with CORS=true, and CORS_ALLOW_ORIGINS set to allow this site. {isError && } {adminOpen && setAdminOpen(false)} />} ; }