feat: show struct schema in output

This commit is contained in:
Joel
2025-08-27 11:15:41 +08:00
parent da48e54778
commit f24f573731
7 changed files with 42 additions and 12 deletions

View File

@@ -44,7 +44,7 @@ const Field: FC<Props> = ({
/>
)}
<div className={cn('system-sm-medium ml-[7px] h-6 truncate leading-6 text-text-secondary', isRoot && rootClassName)}>{name}</div>
<div className='system-xs-regular ml-3 shrink-0 leading-6 text-text-tertiary'>{getFieldType(payload)}</div>
<div className='system-xs-regular ml-3 shrink-0 leading-6 text-text-tertiary'>{getFieldType(payload)}{payload.schemaType && ` (${payload.schemaType})`}</div>
{required && <div className='system-2xs-medium-uppercase ml-3 leading-6 text-text-warning'>{t('app.structOutput.required')}</div>}
</div>
{payload.description && (

View File

@@ -1,3 +1,5 @@
import { useSchemaTypeDefinitions } from '@/service/use-common'
type AnyObj = Record<string, any> | null
// only compare type in object
@@ -29,3 +31,17 @@ export function deepEqualByType(a: AnyObj, b: AnyObj): boolean {
return cmp(a, b)
}
const useMatchSchemaType = () => {
const { data: schemaTypeDefinitions } = useSchemaTypeDefinitions()
const getMatchedSchemaType = (obj: AnyObj): string => {
if(!schemaTypeDefinitions) return ''
const matched = schemaTypeDefinitions.find(def => deepEqualByType(obj, def.schema))
return matched ? matched.name : ''
}
return {
getMatchedSchemaType,
}
}
export default useMatchSchemaType

View File

@@ -55,7 +55,7 @@ export type Field = {
items?: ArrayItems // Array has items. Define the item type
enum?: SchemaEnumType // Enum values
additionalProperties?: false // Required in object by api. Just set false
alias?: string // Alias of the field
schemaType?: string // an another type defined in backend schemas
}
export type StructuredOutput = {

View File

@@ -10,14 +10,11 @@ export const checkNodeValid = (_payload: LLMNodeType) => {
}
export const getFieldType = (field: Field) => {
const { type, items, alias } = field
if (type !== Type.array || !items) {
if (alias)
return alias
const { type, items } = field
if (type !== Type.array || !items)
return type
}
return ArrayType[items.type]
return ArrayType[items.type as keyof typeof ArrayType]
}
export const getHasChildren = (schema: Field) => {

View File

@@ -13,6 +13,7 @@ import StructureOutputItem from '@/app/components/workflow/nodes/_base/component
import { useStore } from '@/app/components/workflow/store'
import { wrapStructuredVarItem } from '@/app/components/workflow/utils/tool'
import { useInitial } from './use-initial'
import useMatchSchemaType from '../_base/components/variable/use-match-schema-type'
const i18nPrefix = 'workflow.nodes.tool'
@@ -41,6 +42,7 @@ const Panel: FC<NodePanelProps<ToolNodeType>> = ({
const [collapsed, setCollapsed] = React.useState(false)
const pipelineId = useStore(s => s.pipelineId)
const setShowInputFieldPanel = useStore(s => s.setShowInputFieldPanel)
const { getMatchedSchemaType } = useMatchSchemaType()
if (isLoading) {
return <div className='flex h-[200px] items-center justify-center'>
@@ -122,7 +124,7 @@ const Panel: FC<NodePanelProps<ToolNodeType>> = ({
{outputItem.value?.type === 'object' ? (
<StructureOutputItem
rootClassName='code-sm-semibold text-text-secondary'
payload={wrapStructuredVarItem(outputItem)} />
payload={wrapStructuredVarItem(outputItem, getMatchedSchemaType(outputItem.value))} />
) : (
<VarItem
name={outputItem.name}

View File

@@ -50,6 +50,7 @@ export const CHUNK_TYPE_MAP = {
qa_chunks: 'QAStructureChunk',
}
// deprecated, use schemaType in llm/types.ts instead
export const getOutputVariableAlias = (variable: Record<string, any>) => {
if (variable?.general_chunks)
return CHUNK_TYPE_MAP.general_chunks
@@ -60,16 +61,16 @@ export const getOutputVariableAlias = (variable: Record<string, any>) => {
if (variable?.file_type)
return 'file'
}
export const wrapStructuredVarItem = (outputItem: any): StructuredOutput => {
export const wrapStructuredVarItem = (outputItem: any, matchedSchemaType: string): StructuredOutput => {
const dataType = Type.object
// console.log(outputItem)
return {
schema: {
type: dataType,
properties: {
[outputItem.name]: {
...outputItem.value,
alias: getOutputVariableAlias(outputItem.value?.properties),
schemaType: matchedSchemaType,
},
},
additionalProperties: false,

View File

@@ -60,3 +60,17 @@ export const useFilePreview = (fileID: string) => {
enabled: !!fileID,
})
}
type SchemaTypeDefinition = {
name: string
schema: {
properties: Record<string, any>
}
}
export const useSchemaTypeDefinitions = () => {
return useQuery<SchemaTypeDefinition[]>({
queryKey: [NAME_SPACE, 'schema-type-definitions'],
queryFn: () => get<SchemaTypeDefinition[]>('/spec/schema-definitions'),
})
}