100 lines
3.9 KiB
TypeScript
100 lines
3.9 KiB
TypeScript
"use client"
|
|
|
|
import { OrgSettingsSection } from "@/components/admin/settings/org-settings-form"
|
|
import { useOrgSettingsStore } from "@/lib/admin-settings/org-settings-store"
|
|
import { Label } from "@/components/ui/label"
|
|
import { Switch } from "@/components/ui/switch"
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
import { Input } from "@/components/ui/input"
|
|
|
|
export function AiAssistantSection() {
|
|
const aiAssistant = useOrgSettingsStore((s) => s.aiAssistant)
|
|
const setAiAssistant = useOrgSettingsStore((s) => s.setAiAssistant)
|
|
const effective = useOrgSettingsStore((s) => s.meta?.effective.ai_assistant)
|
|
|
|
const enabled = effective?.enabled ?? aiAssistant.enabled
|
|
|
|
return (
|
|
<OrgSettingsSection
|
|
title="UltiAI"
|
|
description="Assistant IA intégré (OpenWebUI) avec gateway LLM, tools et sync Nextcloud."
|
|
policySection="ai_assistant"
|
|
>
|
|
<Card>
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between gap-4">
|
|
<div>
|
|
<CardTitle className="text-sm font-medium">Assistant IA</CardTitle>
|
|
<CardDescription>
|
|
Chat standalone et panneaux contextuels mail/drive/contacts.
|
|
</CardDescription>
|
|
</div>
|
|
<Switch
|
|
checked={enabled}
|
|
onCheckedChange={(v) => setAiAssistant({ enabled: v })}
|
|
/>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent className="grid gap-4 sm:grid-cols-2">
|
|
<div className="space-y-2 sm:col-span-2">
|
|
<Label>Chemin public (proxy)</Label>
|
|
<Input
|
|
value={aiAssistant.public_path}
|
|
onChange={(e) => setAiAssistant({ public_path: e.target.value })}
|
|
placeholder="/ai"
|
|
/>
|
|
</div>
|
|
<div className="space-y-2 sm:col-span-2">
|
|
<Label>URL interne OpenWebUI</Label>
|
|
<Input
|
|
value={aiAssistant.openwebui_internal_url}
|
|
onChange={(e) => setAiAssistant({ openwebui_internal_url: e.target.value })}
|
|
placeholder="http://openwebui:8080"
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>Modèle par défaut</Label>
|
|
<Input
|
|
value={aiAssistant.default_model}
|
|
onChange={(e) => setAiAssistant({ default_model: e.target.value })}
|
|
placeholder="gpt-4o"
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>Chemin historique NC</Label>
|
|
<Input
|
|
value={aiAssistant.chat_nc_path}
|
|
onChange={(e) => setAiAssistant({ chat_nc_path: e.target.value })}
|
|
placeholder="/.ultimail/ai/chats"
|
|
/>
|
|
</div>
|
|
<div className="flex items-center justify-between gap-4 sm:col-span-2">
|
|
<div>
|
|
<Label>Embed temporaire par défaut</Label>
|
|
<p className="text-xs text-muted-foreground">
|
|
Les panneaux mail/drive/contacts ne sauvegardent pas l'historique.
|
|
</p>
|
|
</div>
|
|
<Switch
|
|
checked={aiAssistant.embed_default_temporary}
|
|
onCheckedChange={(v) => setAiAssistant({ embed_default_temporary: v })}
|
|
/>
|
|
</div>
|
|
<div className="flex items-center justify-between gap-4 sm:col-span-2">
|
|
<div>
|
|
<Label>Sync historique Nextcloud</Label>
|
|
<p className="text-xs text-muted-foreground">
|
|
Pipeline OpenWebUI → fichiers .ultichat.json sur le drive utilisateur.
|
|
</p>
|
|
</div>
|
|
<Switch
|
|
checked={aiAssistant.chat_sync_enabled}
|
|
onCheckedChange={(v) => setAiAssistant({ chat_sync_enabled: v })}
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</OrgSettingsSection>
|
|
)
|
|
}
|