"use client" import { useEffect, useState } from "react" import { Plus, Trash2 } from "lucide-react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { useLLMSettings, useUpdateLLMSettings, } from "@/lib/api/hooks/use-contact-discovery" import type { ApiLLMProvider, ApiLLMSettings } from "@/lib/contacts/discovery-types" import { LLMModelSuggestInput } from "@/components/gmail/settings/automation/llm-model-suggest-input" import { AutomationTabMasonry } from "@/components/gmail/settings/automation/automation-tab-masonry" import { CONTACTS_MUTED_TEXT, CONTACTS_PRIMARY_BTN_CLASS, } from "@/lib/contacts-chrome-classes" import { cn } from "@/lib/utils" function emptyProvider(): ApiLLMProvider { return { id: crypto.randomUUID(), name: "", base_url: "https://api.openai.com/v1", api_key: "", default_model: "gpt-4o-mini", } } export function LLMProvidersPanel() { const { data: remote, isLoading } = useLLMSettings() const updateSettings = useUpdateLLMSettings() const [draft, setDraft] = useState({ default_provider_id: "", providers: [], }) const [saved, setSaved] = useState(false) useEffect(() => { if (remote) { setDraft({ ...remote, providers: remote.providers ?? [], }) } }, [remote]) function updateProvider(index: number, patch: Partial) { setDraft((prev) => { const providers = [...prev.providers] providers[index] = { ...providers[index], ...patch } return { ...prev, providers } }) } function addProvider() { const p = emptyProvider() setDraft((prev) => ({ ...prev, providers: [...prev.providers, p], default_provider_id: prev.default_provider_id || p.id, })) } function removeProvider(index: number) { setDraft((prev) => { const removed = prev.providers[index] const providers = prev.providers.filter((_, i) => i !== index) let defaultId = prev.default_provider_id if (defaultId === removed?.id) { defaultId = providers[0]?.id ?? "" } return { ...prev, providers, default_provider_id: defaultId } }) } async function handleSave() { await updateSettings.mutateAsync(draft) setSaved(true) setTimeout(() => setSaved(false), 2000) } if (isLoading) { return

Chargement…

} return (

Fournisseurs LLM

API OpenAI-compatibles pour l'enrichissement des contacts et le tri par règles.

{draft.providers.map((provider, index) => (
{provider.name || `Fournisseur ${index + 1}`}
updateProvider(index, { name: e.target.value })} placeholder="OpenAI" />
updateProvider(index, { base_url: e.target.value })} placeholder="https://api.openai.com/v1" />
updateProvider(index, { api_key: e.target.value })} placeholder="sk-…" />
updateProvider(index, { default_model })} placeholder="gpt-4o-mini" />
))}

Découverte de contacts

setDraft((p) => ({ ...p, contact_discovery_model: e.target.value })) } placeholder="Laisser vide pour utiliser le modèle par défaut du fournisseur" />
) }