diff --git a/frontend/app/[locale]/agents/components/agentConfig/tool/ToolConfigModal.tsx b/frontend/app/[locale]/agents/components/agentConfig/tool/ToolConfigModal.tsx index bd822b243..a29c1ac33 100644 --- a/frontend/app/[locale]/agents/components/agentConfig/tool/ToolConfigModal.tsx +++ b/frontend/app/[locale]/agents/components/agentConfig/tool/ToolConfigModal.tsx @@ -24,12 +24,8 @@ import { KnowledgeBase } from "@/types/knowledgeBase"; import ToolTestPanel from "./ToolTestPanel"; import { updateToolConfig } from "@/services/agentConfigService"; import KnowledgeBaseSelectorModal from "@/components/tool-config/KnowledgeBaseSelectorModal"; -import { - useKnowledgeBasesForToolConfig, -} from "@/hooks/useKnowledgeBaseSelector"; -import { - useKnowledgeBaseConfigChangeHandler, -} from "@/hooks/useKnowledgeBaseConfigChangeHandler"; +import { useKnowledgeBasesForToolConfig } from "@/hooks/useKnowledgeBaseSelector"; +import { useKnowledgeBaseConfigChangeHandler } from "@/hooks/useKnowledgeBaseConfigChangeHandler"; import { API_ENDPOINTS } from "@/services/api"; import log from "@/lib/logger"; @@ -95,6 +91,8 @@ export default function ToolConfigModal({ // DataMate URL from knowledge base configuration const [knowledgeBaseDataMateUrl, setKnowledgeBaseDataMateUrl] = useState(""); + // Track if knowledge base config has changed (server_url or api_key changed) + const [hasKbConfigChanged, setHasKbConfigChanged] = useState(false); // Track if user has manually modified the datamate URL field const [hasUserModifiedDatamateUrl, setHasUserModifiedDatamateUrl] = useState(false); @@ -206,12 +204,31 @@ export default function ToolConfigModal({ // Handle config change: clear knowledge base selection and refetch // Uses shared hook for both Dify and DataMate tools const handleKbConfigChange = useCallback(() => { + // Mark that config has changed - this prevents restoring from initialParams + setHasKbConfigChanged(true); + // Clear previous knowledge base selection setSelectedKbIds([]); setSelectedKbDisplayNames([]); + + // Clear form value for knowledge base field (index_names or dataset_ids) + const kbFieldIndex = currentParams.findIndex( + (p) => p.name === "index_names" || p.name === "dataset_ids" + ); + if (kbFieldIndex >= 0) { + form.setFieldValue(`param_${kbFieldIndex}`, []); + // Also clear the value in currentParams + const updatedParams = [...currentParams]; + updatedParams[kbFieldIndex] = { + ...updatedParams[kbFieldIndex], + value: [], + }; + setCurrentParams(updatedParams); + } + // Refetch knowledge bases with new config refetchKnowledgeBases(); - }, [refetchKnowledgeBases]); + }, [refetchKnowledgeBases, currentParams, form]); useKnowledgeBaseConfigChangeHandler({ toolKbType, @@ -274,6 +291,7 @@ export default function ToolConfigModal({ if (!isOpen) { setModalOpened(false); setKnowledgeBaseDataMateUrl(""); + setHasKbConfigChanged(false); } }, [isOpen]); @@ -513,7 +531,9 @@ export default function ToolConfigModal({ if (selectedKbIds.length > 0 && knowledgeBases.length > 0) { const displayNames = selectedKbIds.map((id) => { // Use robust ID comparison - const kb = knowledgeBases.find((k) => String(k.id).trim() === String(id).trim()); + const kb = knowledgeBases.find( + (k) => String(k.id).trim() === String(id).trim() + ); return kb?.display_name || kb?.name || id; }); setSelectedKbDisplayNames(displayNames); @@ -531,7 +551,9 @@ export default function ToolConfigModal({ setSelectedKbIds(validKbIds); // Also update display names const displayNames = validKbIds.map((id) => { - const kb = knowledgeBases.find((k) => String(k.id).trim() === String(id).trim()); + const kb = knowledgeBases.find( + (k) => String(k.id).trim() === String(id).trim() + ); return kb?.display_name || kb?.name || id; }); setSelectedKbDisplayNames(displayNames); @@ -542,7 +564,16 @@ export default function ToolConfigModal({ // Force sync selectedKbIds when modal is about to open (kbSelectorVisible changes to true) // This ensures the modal receives the correct selected IDs useEffect(() => { - if (kbSelectorVisible && selectedKbIds.length === 0 && initialParams.length > 0) { + // Skip if config has changed - don't restore from initialParams after server_url/api_key change + if (hasKbConfigChanged) { + return; + } + + if ( + kbSelectorVisible && + selectedKbIds.length === 0 && + initialParams.length > 0 + ) { // Parse initial index_names/dataset_ids value for knowledge base selection if (toolRequiresKbSelection) { const kbParam = initialParams.find( @@ -568,13 +599,45 @@ export default function ToolConfigModal({ } } } - }, [kbSelectorVisible, initialParams, toolRequiresKbSelection]); + }, [ + kbSelectorVisible, + initialParams, + toolRequiresKbSelection, + hasKbConfigChanged, + ]); // Trigger refetch when opening for knowledge base tools (with loading state support) // Skip if initial load was already done to avoid duplicate API calls + // Reset when currentAgentId changes (i.e., when switching agents) const hasTriggeredInitialRefetch = useRef(false); + const prevAgentIdRef = useRef(undefined); + + // Reset refetch flag when switching agents and invalidate cache to force fresh fetch + useEffect(() => { + if (currentAgentId !== prevAgentIdRef.current) { + prevAgentIdRef.current = currentAgentId; + hasTriggeredInitialRefetch.current = false; + + // Invalidate knowledge base cache when switching agents to force fresh fetch + // This ensures we get the correct knowledge bases for the new agent's config + if (toolKbType === "dify_search") { + queryClient.invalidateQueries({ + queryKey: ["knowledgeBases", "list", "dify_search"], + }); + } else if (toolKbType === "datamate_search") { + queryClient.invalidateQueries({ + queryKey: ["knowledgeBases", "list", "datamate_search"], + }); + } + } + }, [currentAgentId, toolKbType, queryClient]); + useEffect(() => { - if (toolRequiresKbSelection && isOpen && !hasTriggeredInitialRefetch.current) { + if ( + toolRequiresKbSelection && + isOpen && + !hasTriggeredInitialRefetch.current + ) { hasTriggeredInitialRefetch.current = true; // For Dify, only refetch if we have valid config if (toolKbType === "dify_search") { @@ -1154,7 +1217,10 @@ export default function ToolConfigModal({ ); } // Check if protocol is http or https - if (url.protocol !== "http:" && url.protocol !== "https:") { + if ( + url.protocol !== "http:" && + url.protocol !== "https:" + ) { return Promise.reject( t("knowledgeBase.error.invalidUrlProtocol") );