mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-18 12:55:56 +08:00
feat: output var struct
This commit is contained in:
parent
8fb24bf1ca
commit
e32cb0fdf8
@ -3,6 +3,7 @@ import ChartView from './chartView'
|
|||||||
import CardView from './cardView'
|
import CardView from './cardView'
|
||||||
import TracingPanel from './tracing/panel'
|
import TracingPanel from './tracing/panel'
|
||||||
import ApikeyInfoPanel from '@/app/components/app/overview/apikey-info-panel'
|
import ApikeyInfoPanel from '@/app/components/app/overview/apikey-info-panel'
|
||||||
|
import Test from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/test'
|
||||||
|
|
||||||
export type IDevelopProps = {
|
export type IDevelopProps = {
|
||||||
params: { appId: string }
|
params: { appId: string }
|
||||||
@ -13,6 +14,7 @@ const Overview = async ({
|
|||||||
}: IDevelopProps) => {
|
}: IDevelopProps) => {
|
||||||
return (
|
return (
|
||||||
<div className="h-full px-4 sm:px-12 py-6 overflow-scroll bg-chatbot-bg">
|
<div className="h-full px-4 sm:px-12 py-6 overflow-scroll bg-chatbot-bg">
|
||||||
|
<Test />
|
||||||
<ApikeyInfoPanel />
|
<ApikeyInfoPanel />
|
||||||
<TracingPanel />
|
<TracingPanel />
|
||||||
<CardView appId={appId} />
|
<CardView appId={appId} />
|
||||||
|
@ -16,9 +16,6 @@ import type { ModelConfig, PromptVariable } from '@/models/debug'
|
|||||||
import type { AppType } from '@/types/app'
|
import type { AppType } from '@/types/app'
|
||||||
import { ModelModeType } from '@/types/app'
|
import { ModelModeType } from '@/types/app'
|
||||||
|
|
||||||
import mockStructData from '@/app/components/workflow/nodes/llm/mock-struct-data'
|
|
||||||
import ObjectChildrenTreePanel from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel'
|
|
||||||
|
|
||||||
const Config: FC = () => {
|
const Config: FC = () => {
|
||||||
const {
|
const {
|
||||||
mode,
|
mode,
|
||||||
@ -62,13 +59,6 @@ const Config: FC = () => {
|
|||||||
<div
|
<div
|
||||||
className="grow h-0 relative px-6 pb-[50px] overflow-y-auto"
|
className="grow h-0 relative px-6 pb-[50px] overflow-y-auto"
|
||||||
>
|
>
|
||||||
<div className='mb-2'>
|
|
||||||
<ObjectChildrenTreePanel
|
|
||||||
root={{ nodeName: 'LLM', attrName: 'structured_output' }}
|
|
||||||
payload={mockStructData}
|
|
||||||
onSelect={() => { }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/* Template */}
|
{/* Template */}
|
||||||
<ConfigPrompt
|
<ConfigPrompt
|
||||||
mode={mode as AppType}
|
mode={mode as AppType}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Type } from '../../../../llm/types'
|
import { Type } from '../../../../../llm/types'
|
||||||
import { getFieldType } from '../../../../llm/utils'
|
import { getFieldType } from '../../../../../llm/utils'
|
||||||
import type { Field as FieldType } from '../../../../llm/types'
|
import type { Field as FieldType } from '../../../../../llm/types'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import TreeIndentLine from './tree-indent-line'
|
import TreeIndentLine from '../tree-indent-line'
|
||||||
import { RiMoreFill } from '@remixicon/react'
|
import { RiMoreFill } from '@remixicon/react'
|
||||||
import Tooltip from '@/app/components/base/tooltip'
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -26,7 +26,7 @@ const Field: FC<Props> = ({
|
|||||||
<div>
|
<div>
|
||||||
<Tooltip popupContent={t('app.structOutput.moreFillTip')} disabled={depth !== MAX_DEPTH + 1}>
|
<Tooltip popupContent={t('app.structOutput.moreFillTip')} disabled={depth !== MAX_DEPTH + 1}>
|
||||||
<div className={cn('flex pr-2 items-center justify-between rounded-md hover:bg-state-base-hover', depth !== MAX_DEPTH + 1 && 'cursor-pointer')}>
|
<div className={cn('flex pr-2 items-center justify-between rounded-md hover:bg-state-base-hover', depth !== MAX_DEPTH + 1 && 'cursor-pointer')}>
|
||||||
<div className='grow flex items-center'>
|
<div className='grow flex items-stretch'>
|
||||||
<TreeIndentLine depth={depth} isMoreFill={depth === MAX_DEPTH + 1} />
|
<TreeIndentLine depth={depth} isMoreFill={depth === MAX_DEPTH + 1} />
|
||||||
{depth === MAX_DEPTH + 1 ? (
|
{depth === MAX_DEPTH + 1 ? (
|
||||||
<RiMoreFill className='w-3 h-3 text-text-tertiary' />
|
<RiMoreFill className='w-3 h-3 text-text-tertiary' />
|
@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type { Field as FieldType, StructuredOutput } from '../../../../llm/types'
|
import type { Field as FieldType, StructuredOutput } from '../../../../../llm/types'
|
||||||
import Field from './field'
|
import Field from './field'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -10,7 +10,7 @@ type Props = {
|
|||||||
onSelect: (field: FieldType) => void
|
onSelect: (field: FieldType) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjectChildrenTreePanel: FC<Props> = ({
|
const PickerPanel: FC<Props> = ({
|
||||||
root,
|
root,
|
||||||
payload,
|
payload,
|
||||||
}) => {
|
}) => {
|
||||||
@ -38,4 +38,4 @@ const ObjectChildrenTreePanel: FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default React.memo(ObjectChildrenTreePanel)
|
export default React.memo(PickerPanel)
|
@ -0,0 +1,58 @@
|
|||||||
|
'use client'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import { Type } from '../../../../../llm/types'
|
||||||
|
import { getFieldType } from '../../../../../llm/utils'
|
||||||
|
import type { Field as FieldType } from '../../../../../llm/types'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
import TreeIndentLine from '../tree-indent-line'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
const MAX_DEPTH = 10
|
||||||
|
|
||||||
|
type Props = { name: string, payload: FieldType, depth?: number }
|
||||||
|
|
||||||
|
const Field: FC<Props> = ({
|
||||||
|
name,
|
||||||
|
payload,
|
||||||
|
depth = 1,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
if (depth > MAX_DEPTH + 1)
|
||||||
|
return null
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<div className={cn('flex pr-2')}>
|
||||||
|
<TreeIndentLine depth={depth} />
|
||||||
|
<div>
|
||||||
|
<div className='flex'>
|
||||||
|
<div className='h-6 truncate system-sm-medium text-text-secondary leading-6'>{name}</div>
|
||||||
|
<div className='ml-3 shrink-0 system-xs-regular text-text-tertiary leading-6'>{getFieldType(payload)}</div>
|
||||||
|
<div className='ml-3 text-text-warning system-2xs-medium-uppercase leading-6'>Required</div>
|
||||||
|
</div>
|
||||||
|
{payload.description && (
|
||||||
|
<div className='system-xs-regular text-text-tertiary truncate'>{payload.description}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{payload.type === Type.object && payload.properties && (
|
||||||
|
<div>
|
||||||
|
{Object.keys(payload.properties).map(name => (
|
||||||
|
<Field
|
||||||
|
key={name}
|
||||||
|
name={name}
|
||||||
|
payload={payload.properties?.[name] as FieldType}
|
||||||
|
depth={depth + 1}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default React.memo(Field)
|
@ -0,0 +1,28 @@
|
|||||||
|
'use client'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import type { StructuredOutput } from '../../../../../llm/types'
|
||||||
|
import Field from './field'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
payload: StructuredOutput
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShowPanel: FC<Props> = ({
|
||||||
|
payload,
|
||||||
|
}) => {
|
||||||
|
const schema = payload.schema
|
||||||
|
const fieldNames = Object.keys(schema.properties)
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{fieldNames.map(name => (
|
||||||
|
<Field
|
||||||
|
key={name}
|
||||||
|
name={name}
|
||||||
|
payload={schema.properties[name]}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default React.memo(ShowPanel)
|
@ -0,0 +1,24 @@
|
|||||||
|
'use client'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import mockStructData from '@/app/components/workflow/nodes/llm/mock-struct-data'
|
||||||
|
import PickerPanel from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker'
|
||||||
|
import ShowPanel from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show'
|
||||||
|
|
||||||
|
const Test: FC = () => {
|
||||||
|
return (
|
||||||
|
<div className='mb-2'>
|
||||||
|
<div className='my-2 w-[404px] bg-white'>
|
||||||
|
<ShowPanel
|
||||||
|
payload={mockStructData}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<PickerPanel
|
||||||
|
root={{ nodeName: 'LLM', attrName: 'structured_output' }}
|
||||||
|
payload={mockStructData}
|
||||||
|
onSelect={() => { }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default React.memo(Test)
|
@ -16,7 +16,7 @@ const TreeIndentLine: FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<div className='ml-2.5 mr-2.5 flex space-x-[12px]'>
|
<div className='ml-2.5 mr-2.5 flex space-x-[12px]'>
|
||||||
{depthArray.map(d => (
|
{depthArray.map(d => (
|
||||||
<div key={d} className={cn('w-px bg-divider-regular', isMoreFill ? 'h-3' : 'h-6')}></div>
|
<div key={d} className={cn('w-px bg-divider-regular')}></div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user