"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 (
); } return (
Configure how the AI responds to your queries. Citations add source references, and the system instructions personalize the response style. {/* Citations Card */} Citation Configuration Control whether AI responses include citations to source documents

When enabled, AI responses will include citations in [citation:id] format linking to source documents.

{!enableCitations && ( Citations are currently disabled. AI responses will not include source references. You can re-enable this anytime. )} {enableCitations && ( Citations are enabled. When answering questions, the AI will reference source documents using the [citation:id] format. )}
{/* SearchSpace System Instructions Card */} SearchSpace System Instructions Add system instructions to guide the AI's response style and behavior

Provide specific guidelines for how you want the AI to respond. These instructions will be applied to all answers.