diff --git a/client/src/components/DynamicJsonForm.tsx b/client/src/components/DynamicJsonForm.tsx index ecd150f22..8ef722cd1 100644 --- a/client/src/components/DynamicJsonForm.tsx +++ b/client/src/components/DynamicJsonForm.tsx @@ -27,7 +27,11 @@ interface DynamicJsonFormProps { } export interface DynamicJsonFormRef { - validateJson: () => { isValid: boolean; error: string | null }; + validateJson: () => { + isValid: boolean; + error: string | null; + value?: JsonValue; + }; hasJsonError: () => boolean; } @@ -222,7 +226,7 @@ const DynamicJsonForm = forwardRef( } onChange(parsed); setJsonError(undefined); - return { isValid: true, error: null }; + return { isValid: true, error: null, value: parsed }; } catch (err) { const errorMessage = err instanceof Error ? err.message : "Invalid JSON"; diff --git a/client/src/components/ToolResults.tsx b/client/src/components/ToolResults.tsx index 38d1d0382..d036298b9 100644 --- a/client/src/components/ToolResults.tsx +++ b/client/src/components/ToolResults.tsx @@ -22,17 +22,14 @@ const checkContentCompatibility = ( text?: string; [key: string]: unknown; }>, -): { isCompatible: boolean; message: string } => { +): { hasMatch: boolean; message: string } | null => { // Look for at least one text content block that matches the structured content const textBlocks = unstructuredContent.filter( (block) => block.type === "text", ); if (textBlocks.length === 0) { - return { - isCompatible: false, - message: "No text blocks to match structured content", - }; + return null; } // Check if any text block contains JSON that matches the structured content @@ -49,7 +46,7 @@ const checkContentCompatibility = ( if (isEqual) { return { - isCompatible: true, + hasMatch: true, message: `Structured content matches text block${textBlocks.length > 1 ? " (multiple blocks)" : ""}${unstructuredContent.length > textBlocks.length ? " + other content" : ""}`, }; } @@ -59,10 +56,7 @@ const checkContentCompatibility = ( } } - return { - isCompatible: false, - message: "No text block matches structured content", - }; + return null; }; const ToolResults = ({ @@ -195,16 +189,9 @@ const ToolResults = ({
Unstructured Content:
- {compatibilityResult && ( -
- {compatibilityResult.isCompatible ? "✓" : "⚠"}{" "} - {compatibilityResult.message} + {compatibilityResult?.hasMatch && ( +
+ ✓ {compatibilityResult.message}
)} diff --git a/client/src/components/ToolsTab.tsx b/client/src/components/ToolsTab.tsx index 339ba7c61..afc4e66b9 100644 --- a/client/src/components/ToolsTab.tsx +++ b/client/src/components/ToolsTab.tsx @@ -181,14 +181,30 @@ const ToolsTab = ({ const { copied, setCopied } = useCopy(); // Function to check if any form has validation errors + // When validateChildren is true, also collects fresh parsed values from JSON editors const checkValidationErrors = (validateChildren: boolean = false) => { - const errors = Object.values(formRefs.current).some( - (ref) => - ref && - (validateChildren ? !ref.validateJson().isValid : ref.hasJsonError()), - ); - setHasValidationErrors(errors); - return errors; + const freshValues: Record = {}; + let hasErrors = false; + + for (const [key, ref] of Object.entries(formRefs.current)) { + if (!ref) continue; + if (validateChildren) { + const result = ref.validateJson(); + if (!result.isValid) { + hasErrors = true; + } + if (result.value !== undefined) { + freshValues[key] = result.value; + } + } else { + if (ref.hasJsonError()) { + hasErrors = true; + } + } + } + + setHasValidationErrors(hasErrors); + return { hasErrors, freshValues }; }; useEffect(() => { @@ -333,8 +349,8 @@ const ToolsTab = ({ name={key} checked={params[key] === null} onCheckedChange={(checked: boolean) => - setParams({ - ...params, + setParams((prev) => ({ + ...prev, [key]: checked ? null : prop.type === "array" @@ -349,7 +365,7 @@ const ToolsTab = ({ prop.type === "integer" ? undefined : undefined, - }) + })) } />