"use client"; import { Info, RotateCcw, Save } from "lucide-react"; import { useEffect, useState } from "react"; import { toast } from "sonner"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Label } from "@/components/ui/label"; import { Separator } from "@/components/ui/separator"; import { Skeleton } from "@/components/ui/skeleton"; import { Switch } from "@/components/ui/switch"; import { Textarea } from "@/components/ui/textarea"; import { useSearchSpace } from "@/hooks/use-search-space"; interface PromptConfigManagerProps { searchSpaceId: number; } export function PromptConfigManager({ searchSpaceId }: PromptConfigManagerProps) { const { searchSpace, loading, fetchSearchSpace } = useSearchSpace({ searchSpaceId, autoFetch: true, }); const [enableCitations, setEnableCitations] = useState(true); const [customInstructions, setCustomInstructions] = useState(""); const [saving, setSaving] = useState(false); const [hasChanges, setHasChanges] = useState(false); // Initialize state from fetched search space useEffect(() => { if (searchSpace) { setEnableCitations(searchSpace.citations_enabled); setCustomInstructions(searchSpace.qna_custom_instructions || ""); setHasChanges(false); } }, [searchSpace]); // Track changes useEffect(() => { if (searchSpace) { const currentCustom = searchSpace.qna_custom_instructions || ""; const changed = searchSpace.citations_enabled !== enableCitations || currentCustom !== customInstructions; setHasChanges(changed); } }, [searchSpace, enableCitations, customInstructions]); const handleSave = async () => { try { setSaving(true); // Prepare payload with simplified schema const payload: any = { citations_enabled: enableCitations, qna_custom_instructions: customInstructions.trim() || "", }; // Only send request if we have something to update if (Object.keys(payload).length > 0) { const response = await fetch( `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${searchSpaceId}`, { method: "PUT", headers: { "Content-Type": "application/json", Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`, }, body: JSON.stringify(payload), } ); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.detail || "Failed to save prompt configuration"); } toast.success("Prompt configuration saved successfully"); } setHasChanges(false); // Refresh to get updated data await fetchSearchSpace(); } catch (error: any) { console.error("Error saving prompt configuration:", error); toast.error(error.message || "Failed to save prompt configuration"); } finally { setSaving(false); } }; const handleReset = () => { if (searchSpace) { setEnableCitations(searchSpace.citations_enabled); setCustomInstructions(searchSpace.qna_custom_instructions || ""); setHasChanges(false); } }; if (loading) { return (
When enabled, AI responses will include citations in [citation:id] format linking to source documents.
Provide specific guidelines for how you want the AI to respond. These instructions will be applied to all answers.