mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
fix: json schema
This commit is contained in:
@ -9,7 +9,7 @@ import type { ValueSelector } from '@/app/components/workflow/types'
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className?: string
|
className?: string
|
||||||
root: { nodeId?: string, nodeName?: string, attrName: string }
|
root: { nodeId?: string, nodeName?: string, attrName: string, attrAlias?: string }
|
||||||
payload: StructuredOutput
|
payload: StructuredOutput
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
onSelect?: (valueSelector: ValueSelector) => void
|
onSelect?: (valueSelector: ValueSelector) => void
|
||||||
@ -52,8 +52,7 @@ export const PickerPanelMain: FC<Props> = ({
|
|||||||
)}
|
)}
|
||||||
<div className='system-sm-medium text-text-secondary'>{root.attrName}</div>
|
<div className='system-sm-medium text-text-secondary'>{root.attrName}</div>
|
||||||
</div>
|
</div>
|
||||||
{/* It must be object */}
|
<div className='system-xs-regular ml-2 truncate text-text-tertiary' title={root.attrAlias || 'object'}>{root.attrAlias || 'object'}</div>
|
||||||
<div className='system-xs-regular ml-2 shrink-0 text-text-tertiary'>object</div>
|
|
||||||
</div>
|
</div>
|
||||||
{fieldNames.map(name => (
|
{fieldNames.map(name => (
|
||||||
<Field
|
<Field
|
||||||
|
|||||||
@ -217,6 +217,7 @@ const findExceptVarInObject = (obj: any, filterVar: (payload: Var, selector: Val
|
|||||||
variable: obj.variable,
|
variable: obj.variable,
|
||||||
type: isFile ? VarType.file : VarType.object,
|
type: isFile ? VarType.file : VarType.object,
|
||||||
children: childrenResult,
|
children: childrenResult,
|
||||||
|
alias: obj.alias,
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -518,41 +519,8 @@ const formatItem = (
|
|||||||
|
|
||||||
case BlockEnum.DataSource: {
|
case BlockEnum.DataSource: {
|
||||||
const payload = data as DataSourceNodeType
|
const payload = data as DataSourceNodeType
|
||||||
const baseVars = DataSourceNodeDefault.getOutputVars?.(payload, ragVars) || []
|
const dataSourceVars = DataSourceNodeDefault.getOutputVars?.(payload, ragVars) || []
|
||||||
if (payload.output_schema?.properties) {
|
res.vars = dataSourceVars
|
||||||
const dynamicOutputSchema: any[] = []
|
|
||||||
Object.keys(payload.output_schema.properties).forEach((outputKey) => {
|
|
||||||
const output = payload.output_schema!.properties[outputKey]
|
|
||||||
const dataType = output?.properties?.dify_builtin_type ? output.properties.dify_builtin_type.enum[0] : output.type
|
|
||||||
dynamicOutputSchema.push({
|
|
||||||
variable: outputKey,
|
|
||||||
type: dataType === 'array'
|
|
||||||
? `array[${output.items?.type.slice(0, 1).toLocaleLowerCase()}${output.items?.type.slice(1)}]`
|
|
||||||
: `${dataType.slice(0, 1).toLocaleLowerCase()}${dataType.slice(1)}`,
|
|
||||||
description: output.description,
|
|
||||||
children: output.type === 'object' ? {
|
|
||||||
schema: {
|
|
||||||
type: 'object',
|
|
||||||
properties: Object.fromEntries(
|
|
||||||
Object.entries(output.properties).filter(([key]) => key !== 'dify_builtin_type'),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
} : undefined,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
res.vars = [
|
|
||||||
...baseVars,
|
|
||||||
...dynamicOutputSchema,
|
|
||||||
{
|
|
||||||
variable: 'output',
|
|
||||||
type: VarType.object,
|
|
||||||
children: dynamicOutputSchema,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res.vars = baseVars
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,7 +920,7 @@ export const getVarType = ({
|
|||||||
const isStructuredOutputVar = !!targetVar.children?.schema?.properties
|
const isStructuredOutputVar = !!targetVar.children?.schema?.properties
|
||||||
if (isStructuredOutputVar) {
|
if (isStructuredOutputVar) {
|
||||||
if (valueSelector.length === 2) { // root
|
if (valueSelector.length === 2) { // root
|
||||||
return VarType.object
|
return targetVar.alias || VarType.object
|
||||||
}
|
}
|
||||||
let currProperties = targetVar.children.schema;
|
let currProperties = targetVar.children.schema;
|
||||||
(valueSelector as ValueSelector).slice(2).forEach((key, i) => {
|
(valueSelector as ValueSelector).slice(2).forEach((key, i) => {
|
||||||
|
|||||||
@ -173,7 +173,7 @@ const Item: FC<ItemProps> = ({
|
|||||||
<div title={itemData.des} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable.split('.').slice(-1)[0]}</div>
|
<div title={itemData.des} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable.split('.').slice(-1)[0]}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className='ml-1 shrink-0 text-xs font-normal capitalize text-text-tertiary'>{itemData.type}</div>
|
<div className='ml-1 shrink-0 text-xs font-normal capitalize text-text-tertiary'>{itemData.alias || itemData.type}</div>
|
||||||
{
|
{
|
||||||
(isObj || isStructureOutput) && (
|
(isObj || isStructureOutput) && (
|
||||||
<ChevronRight className={cn('ml-0.5 h-3 w-3 text-text-quaternary', isHovering && 'text-text-tertiary')} />
|
<ChevronRight className={cn('ml-0.5 h-3 w-3 text-text-quaternary', isHovering && 'text-text-tertiary')} />
|
||||||
@ -186,7 +186,7 @@ const Item: FC<ItemProps> = ({
|
|||||||
}}>
|
}}>
|
||||||
{(isStructureOutput || isObj) && (
|
{(isStructureOutput || isObj) && (
|
||||||
<PickerStructurePanel
|
<PickerStructurePanel
|
||||||
root={{ nodeId, nodeName: title, attrName: itemData.variable }}
|
root={{ nodeId, nodeName: title, attrName: itemData.variable, attrAlias: itemData.alias }}
|
||||||
payload={structuredOutput!}
|
payload={structuredOutput!}
|
||||||
onHovering={setIsChildrenHovering}
|
onHovering={setIsChildrenHovering}
|
||||||
onSelect={(valueSelector) => {
|
onSelect={(valueSelector) => {
|
||||||
|
|||||||
@ -58,6 +58,29 @@ const nodeDefault: NodeDefault<DataSourceNodeType> = {
|
|||||||
provider_type,
|
provider_type,
|
||||||
} = payload
|
} = payload
|
||||||
const isLocalFile = provider_type === DataSourceClassification.localFile
|
const isLocalFile = provider_type === DataSourceClassification.localFile
|
||||||
|
const dynamicOutputSchema: any[] = []
|
||||||
|
if (payload.output_schema?.properties) {
|
||||||
|
Object.keys(payload.output_schema.properties).forEach((outputKey) => {
|
||||||
|
const output = payload.output_schema!.properties[outputKey]
|
||||||
|
const dataType = output.type
|
||||||
|
dynamicOutputSchema.push({
|
||||||
|
variable: outputKey,
|
||||||
|
type: dataType === 'array'
|
||||||
|
? `array[${output.items?.type.slice(0, 1).toLocaleLowerCase()}${output.items?.type.slice(1)}]`
|
||||||
|
: `${dataType.slice(0, 1).toLocaleLowerCase()}${dataType.slice(1)}`,
|
||||||
|
description: output.description,
|
||||||
|
alias: output?.properties.dify_builtin_type?.enum?.[0],
|
||||||
|
children: output.type === 'object' ? {
|
||||||
|
schema: {
|
||||||
|
type: 'object',
|
||||||
|
properties: Object.fromEntries(
|
||||||
|
Object.entries(output.properties).filter(([key]) => key !== 'dify_builtin_type'),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
} : undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
...COMMON_OUTPUT.map(item => ({ variable: item.name, type: item.type })),
|
...COMMON_OUTPUT.map(item => ({ variable: item.name, type: item.type })),
|
||||||
...(
|
...(
|
||||||
@ -66,6 +89,7 @@ const nodeDefault: NodeDefault<DataSourceNodeType> = {
|
|||||||
: []
|
: []
|
||||||
),
|
),
|
||||||
...ragVars,
|
...ragVars,
|
||||||
|
...dynamicOutputSchema,
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ const Panel: FC<NodePanelProps<DataSourceNodeType>> = ({ id, data }) => {
|
|||||||
const pipelineId = useStore(s => s.pipelineId)
|
const pipelineId = useStore(s => s.pipelineId)
|
||||||
const setShowInputFieldPanel = useStore(s => s.setShowInputFieldPanel)
|
const setShowInputFieldPanel = useStore(s => s.setShowInputFieldPanel)
|
||||||
const wrapStructuredVarItem = (outputItem: any): StructuredOutput => {
|
const wrapStructuredVarItem = (outputItem: any): StructuredOutput => {
|
||||||
const dataType = outputItem.value?.properties?.dify_builtin_type ? outputItem.value?.properties?.dify_builtin_type.enum[0] : Type.object
|
const dataType = Type.object
|
||||||
const properties = Object.fromEntries(
|
const properties = Object.fromEntries(
|
||||||
Object.entries(outputItem.value?.properties || {}).filter(([key]) => key !== 'dify_builtin_type'),
|
Object.entries(outputItem.value?.properties || {}).filter(([key]) => key !== 'dify_builtin_type'),
|
||||||
) as Record<string, any>
|
) as Record<string, any>
|
||||||
@ -61,6 +61,7 @@ const Panel: FC<NodePanelProps<DataSourceNodeType>> = ({ id, data }) => {
|
|||||||
[outputItem.name]: {
|
[outputItem.name]: {
|
||||||
...outputItem.value,
|
...outputItem.value,
|
||||||
properties,
|
properties,
|
||||||
|
alias: outputItem.value?.properties?.dify_builtin_type?.enum?.[0],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
|
|||||||
@ -55,6 +55,7 @@ export type Field = {
|
|||||||
items?: ArrayItems // Array has items. Define the item type
|
items?: ArrayItems // Array has items. Define the item type
|
||||||
enum?: SchemaEnumType // Enum values
|
enum?: SchemaEnumType // Enum values
|
||||||
additionalProperties?: false // Required in object by api. Just set false
|
additionalProperties?: false // Required in object by api. Just set false
|
||||||
|
alias?: string // Alias of the field
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StructuredOutput = {
|
export type StructuredOutput = {
|
||||||
|
|||||||
@ -10,9 +10,12 @@ export const checkNodeValid = (_payload: LLMNodeType) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getFieldType = (field: Field) => {
|
export const getFieldType = (field: Field) => {
|
||||||
const { type, items } = field
|
const { type, items, alias } = field
|
||||||
if (type !== Type.array || !items)
|
if (type !== Type.array || !items) {
|
||||||
|
if (alias)
|
||||||
|
return alias
|
||||||
return type
|
return type
|
||||||
|
}
|
||||||
|
|
||||||
return ArrayType[items.type]
|
return ArrayType[items.type]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -302,6 +302,7 @@ export type Var = {
|
|||||||
isLoopVariable?: boolean
|
isLoopVariable?: boolean
|
||||||
nodeId?: string
|
nodeId?: string
|
||||||
isRagVariable?: boolean
|
isRagVariable?: boolean
|
||||||
|
alias?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NodeOutPutVar = {
|
export type NodeOutPutVar = {
|
||||||
|
|||||||
Reference in New Issue
Block a user