From 6c73216416eb1307051e954a09a6f59d778706ae Mon Sep 17 00:00:00 2001 From: twwu Date: Thu, 27 Mar 2025 15:11:38 +0800 Subject: [PATCH] feat: update JSON schema handling to convert boolean types to strings and improve JSON validation --- .../json-importer.tsx | 6 +++++- .../json-schema-config.tsx | 7 ++++--- .../components/workflow/nodes/llm/utils.ts | 20 +++++++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx index 8930a6cb41..8f25583962 100644 --- a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx +++ b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx @@ -12,7 +12,7 @@ import { useVisualEditorStore } from './visual-editor/store' import Toast from '@/app/components/base/toast' type JsonImporterProps = { - onSubmit: (schema: string) => void + onSubmit: (schema: any) => void updateBtnWidth: (width: number) => void } @@ -55,6 +55,10 @@ const JsonImporter: FC = ({ const handleSubmit = useCallback(() => { try { const parsedJSON = JSON.parse(json) + if (typeof parsedJSON !== 'object' || Array.isArray(parsedJSON)) { + setParseError(new Error('Root must be an object, not an array or primitive value.')) + return + } const maxDepth = checkDepth(parsedJSON) if (maxDepth > JSON_SCHEMA_MAX_DEPTH) { setParseError({ diff --git a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx index f77781ea8b..bbc8f567f9 100644 --- a/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx +++ b/web/app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx @@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next' import Button from '@/app/components/base/button' import VisualEditor from './visual-editor' import SchemaEditor from './schema-editor' -import { getValidationErrorMessage, jsonToSchema, validateSchemaAgainstDraft7 } from '../../utils' +import { convertBooleanToString, getValidationErrorMessage, jsonToSchema, validateSchemaAgainstDraft7 } from '../../utils' import { MittProvider, VisualEditorContextProvider } from './visual-editor/context' import ErrorMessage from './error-message' import { useVisualEditorStore } from './visual-editor/store' @@ -74,7 +74,8 @@ const JsonSchemaConfig: FC = ({ if (currentTab === value) return if (currentTab === SchemaView.JsonSchema) { try { - const schema = JSON.parse(json) + const parsedJson = JSON.parse(json) + const schema = convertBooleanToString(parsedJson) setParseError(null) const ajvError = validateSchemaAgainstDraft7(schema) if (ajvError.length > 0) { @@ -116,7 +117,7 @@ const JsonSchemaConfig: FC = ({ setJson(JSON.stringify(schema, null, 2)) }, [currentTab]) - const handleSubmit = useCallback((schema: string) => { + const handleSubmit = useCallback((schema: any) => { const jsonSchema = jsonToSchema(schema) as SchemaRoot if (currentTab === SchemaView.VisualEditor) setJsonSchema(jsonSchema) diff --git a/web/app/components/workflow/nodes/llm/utils.ts b/web/app/components/workflow/nodes/llm/utils.ts index 2d8966c828..afeed55a5c 100644 --- a/web/app/components/workflow/nodes/llm/utils.ts +++ b/web/app/components/workflow/nodes/llm/utils.ts @@ -105,3 +105,23 @@ export const getValidationErrorMessage = (errors: ErrorObject[]) => { }).join('; ') return message } + +export const convertBooleanToString = (schema: any) => { + if (schema.type === Type.boolean) + schema.type = Type.string + if (schema.type === Type.array && schema.items && schema.items.type === Type.boolean) + schema.items.type = Type.string + if (schema.type === Type.object) { + schema.properties = Object.entries(schema.properties).reduce((acc, [key, value]) => { + acc[key] = convertBooleanToString(value) + return acc + }, {} as any) + } + if (schema.type === Type.array && schema.items && schema.items.type === Type.object) { + schema.items.properties = Object.entries(schema.items.properties).reduce((acc, [key, value]) => { + acc[key] = convertBooleanToString(value) + return acc + }, {} as any) + } + return schema +}