From 43c66008e4284ce1d80614854c15b1c1b5d9f6f8 Mon Sep 17 00:00:00 2001 From: "DESKTOP-RTLN3BA\\$punk" Date: Fri, 29 May 2026 03:30:22 -0700 Subject: [PATCH] fix(llm-role-manager): synchronize local state with preferences updates - Added useEffect to sync local assignments state with preferences when they change, ensuring the UI reflects the latest data. - Updated state initialization to use null instead of empty strings for clarity in role assignments. - Adjusted role assignment handling to correctly manage "unassigned" values and preserve Auto mode configuration during updates. --- .../components/settings/llm-role-manager.tsx | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/surfsense_web/components/settings/llm-role-manager.tsx b/surfsense_web/components/settings/llm-role-manager.tsx index 17370b8f2..9af9eec27 100644 --- a/surfsense_web/components/settings/llm-role-manager.tsx +++ b/surfsense_web/components/settings/llm-role-manager.tsx @@ -11,7 +11,7 @@ import { RefreshCw, ScanEye, } from "lucide-react"; -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { toast } from "sonner"; import { globalImageGenConfigsAtom, @@ -135,18 +135,39 @@ export function LLMRoleManager({ searchSpaceId }: LLMRoleManagerProps) { const { mutateAsync: updatePreferences } = useAtomValue(updateLLMPreferencesMutationAtom); - const [assignments, setAssignments] = useState(() => ({ - agent_llm_id: preferences.agent_llm_id ?? "", - document_summary_llm_id: preferences.document_summary_llm_id ?? "", - image_generation_config_id: preferences.image_generation_config_id ?? "", - vision_llm_config_id: preferences.vision_llm_config_id ?? "", + const [assignments, setAssignments] = useState>(() => ({ + agent_llm_id: preferences.agent_llm_id ?? null, + document_summary_llm_id: preferences.document_summary_llm_id ?? null, + image_generation_config_id: preferences.image_generation_config_id ?? null, + vision_llm_config_id: preferences.vision_llm_config_id ?? null, })); + // Sync local state when preferences load/change. Without this, the selects + // stay on their initial (often empty) value while the query is in flight, + // so a saved assignment — including Auto mode (id 0) — never appears. + useEffect(() => { + setAssignments({ + agent_llm_id: preferences.agent_llm_id ?? null, + document_summary_llm_id: preferences.document_summary_llm_id ?? null, + image_generation_config_id: preferences.image_generation_config_id ?? null, + vision_llm_config_id: preferences.vision_llm_config_id ?? null, + }); + }, [ + preferences.agent_llm_id, + preferences.document_summary_llm_id, + preferences.image_generation_config_id, + preferences.vision_llm_config_id, + ]); + const [savingRole, setSavingRole] = useState(null); const handleRoleAssignment = useCallback( async (prefKey: string, configId: string) => { - const value = configId === "unassigned" ? "" : parseInt(configId); + // "unassigned" clears the role (null). Every other option — including + // Auto mode, whose config id is 0 — must be sent as-is. Using a falsy + // check here (e.g. `value || undefined`) would drop id 0 and silently + // fail to persist Auto mode. + const value = configId === "unassigned" ? null : Number(configId); setAssignments((prev) => ({ ...prev, [prefKey]: value })); setSavingRole(prefKey); @@ -154,7 +175,7 @@ export function LLMRoleManager({ searchSpaceId }: LLMRoleManagerProps) { try { await updatePreferences({ search_space_id: searchSpaceId, - data: { [prefKey]: value || undefined }, + data: { [prefKey]: value }, }); toast.success("Role assignment updated"); } finally { @@ -325,7 +346,7 @@ export function LLMRoleManager({ searchSpaceId }: LLMRoleManagerProps) { Configuration