Merge remote-tracking branch 'origin/deploy/rag-dev' into deploy/rag-dev

This commit is contained in:
jyong 2025-06-11 17:30:45 +08:00
commit ce8ddae11e
18 changed files with 115 additions and 31 deletions

View File

@ -165,6 +165,8 @@ const ComponentPicker = ({
isSupportFileVar={isSupportFileVar}
onClose={handleClose}
onBlur={handleClose}
showManageInputField={workflowVariableBlock.showManageInputField}
onManageInputField={workflowVariableBlock.onManageInputField}
/>
</div>
)
@ -205,7 +207,7 @@ const ComponentPicker = ({
}
</>
)
}, [allFlattenOptions.length, workflowVariableBlock?.show, refs, isPositioned, floatingStyles, queryString, workflowVariableOptions, handleSelectWorkflowVariable, handleClose, isSupportFileVar])
}, [allFlattenOptions.length, workflowVariableBlock?.show, refs, isPositioned, floatingStyles, queryString, workflowVariableOptions, handleSelectWorkflowVariable, handleClose, isSupportFileVar, workflowVariableBlock?.showManageInputField, workflowVariableBlock?.onManageInputField])
return (
<LexicalTypeaheadMenuPlugin

View File

@ -68,6 +68,8 @@ export type WorkflowVariableBlockType = {
onInsert?: () => void
onDelete?: () => void
getVarType?: GetVarType
showManageInputField?: boolean
onManageInputField?: () => void
}
export type MenuTextMatch = {

View File

@ -52,34 +52,35 @@ const TemplateCard = ({
}, [])
const handleUseTemplate = useCallback(async (payload: Omit<CreateDatasetReq, 'yaml_content'>) => {
try {
const { data: pipelineTemplateInfo } = await getPipelineTemplateInfo()
if (!pipelineTemplateInfo) {
Toast.notify({
type: 'error',
message: t('datasetPipeline.creation.errorTip'),
})
return
}
const request = {
...payload,
yaml_content: pipelineTemplateInfo.export_data,
}
const newDataset = await createEmptyDataset(request)
Toast.notify({
type: 'success',
message: t('app.newApp.appCreated'),
})
if (newDataset.pipeline_id)
await handleCheckPluginDependencies(newDataset.pipeline_id, true)
push(`dataset/${newDataset.id}/pipeline`)
}
catch {
const { data: pipelineTemplateInfo } = await getPipelineTemplateInfo()
if (!pipelineTemplateInfo) {
Toast.notify({
type: 'error',
message: t('datasetPipeline.creation.errorTip'),
})
return
}
const request = {
...payload,
yaml_content: pipelineTemplateInfo.export_data,
}
await createEmptyDataset(request, {
onSuccess: async (newDataset) => {
Toast.notify({
type: 'success',
message: t('app.newApp.appCreated'),
})
if (newDataset.pipeline_id)
await handleCheckPluginDependencies(newDataset.pipeline_id, true)
push(`/datasets/${newDataset.id}/pipeline`)
},
onError: () => {
Toast.notify({
type: 'error',
message: t('datasetPipeline.creation.errorTip'),
})
},
})
}, [getPipelineTemplateInfo, createEmptyDataset, t, handleCheckPluginDependencies, push])
const handleShowTemplateDetails = useCallback(() => {

View File

@ -21,7 +21,7 @@ const DialogWrapper = ({
const close = useCallback(() => onClose?.(), [onClose])
return (
<Transition appear show={show} as={Fragment}>
<Dialog as='div' className='relative z-40' onClose={close}>
<Dialog as='div' className='relative z-[2000]' onClose={close}>
<TransitionChild>
<div className={cn(
'fixed inset-0 bg-black/25',

View File

@ -21,7 +21,7 @@ const DialogWrapper = ({
const close = useCallback(() => onClose?.(), [onClose])
return (
<Transition appear show={show} as={Fragment}>
<Dialog as='div' className='relative z-40' onClose={close}>
<Dialog as='div' className='relative z-[2001]' onClose={close}>
<TransitionChild>
<div className={cn(
'fixed inset-0 bg-black/25',

View File

@ -1251,7 +1251,7 @@ export const useNodesInteractions = () => {
}
else {
// If no nodeId is provided, fall back to the current behavior
const bundledNodes = nodes.filter(node => node.data._isBundled && node.data.type !== BlockEnum.Start && node.data.type !== BlockEnum.DataSource
const bundledNodes = nodes.filter(node => node.data._isBundled && node.data.type !== BlockEnum.Start && node.data.type !== BlockEnum.DataSource && node.data.type !== BlockEnum.KnowledgeBase
&& !node.data.isInIteration && !node.data.isInLoop)
if (bundledNodes.length) {

View File

@ -13,6 +13,7 @@ import PromptEditor from '@/app/components/base/prompt-editor'
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
import Tooltip from '@/app/components/base/tooltip'
import { noop } from 'lodash-es'
import { useStore } from '@/app/components/workflow/store'
type Props = {
instanceId?: string
@ -56,6 +57,9 @@ const Editor: FC<Props> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocus])
const pipelineId = useStore(s => s.pipelineId)
const setShowInputFieldDialog = useStore(s => s.setShowInputFieldDialog)
return (
<div className={cn(className, 'relative')}>
<>
@ -103,6 +107,8 @@ const Editor: FC<Props> = ({
}
return acc
}, {} as any),
showManageInputField: !!pipelineId,
onManageInputField: () => setShowInputFieldDialog?.(true),
}}
onChange={onChange}
editable={!readOnly}

View File

@ -254,7 +254,7 @@ const Editor: FC<Props> = ({
workflowVariableBlock={{
show: true,
variables: nodesOutputVars || [],
getVarType,
getVarType: getVarType as any,
workflowNodesMap: availableNodes.reduce((acc, node) => {
acc[node.id] = {
title: node.data.title,

View File

@ -0,0 +1,38 @@
import { useTranslation } from 'react-i18next'
import { RiAddLine } from '@remixicon/react'
type ManageInputFieldProps = {
onManage: () => void
}
const ManageInputField = ({
onManage,
}: ManageInputFieldProps) => {
const { t } = useTranslation()
return (
<div className='flex items-center border-t border-divider-subtle pt-1'>
<div
className='flex h-8 grow cursor-pointer items-center px-3'
onClick={onManage}
>
<RiAddLine className='mr-1 h-4 w-4 text-text-tertiary' />
<div
className='system-xs-medium truncate text-text-tertiary'
title='Create user input field'
>
{t('pipeline.inputField.create')}
</div>
</div>
<div className='mx-1 h-3 w-[1px] shrink-0 bg-divider-regular'></div>
<div
className='system-xs-medium flex h-8 shrink-0 cursor-pointer items-center justify-center px-3 text-text-tertiary'
onClick={onManage}
>
{t('pipeline.inputField.manage')}
</div>
</div>
)
}
export default ManageInputField

View File

@ -319,6 +319,7 @@ const VarReferencePicker: FC<Props> = ({
return null
}, [isValidVar, isShowAPart, hasValue, t, outputVarNode?.title, outputVarNode?.type, value, type])
return (
<div className={cn(className, !readonly && 'cursor-pointer')}>
<PortalToFollowElem

View File

@ -1,6 +1,6 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import React, { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import VarReferenceVars from './var-reference-vars'
@ -8,6 +8,7 @@ import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflo
import ListEmpty from '@/app/components/base/list-empty'
import { LanguagesSupported } from '@/i18n/language'
import I18n from '@/context/i18n'
import { useStore } from '@/app/components/workflow/store'
type Props = {
vars: NodeOutPutVar[]
@ -25,6 +26,9 @@ const VarReferencePopup: FC<Props> = ({
}) => {
const { t } = useTranslation()
const { locale } = useContext(I18n)
const pipelineId = useStore(s => s.pipelineId)
const showManageRagInputFields = useMemo(() => !!pipelineId, [pipelineId])
const setShowInputFieldDialog = useStore(s => s.setShowInputFieldDialog)
// max-h-[300px] overflow-y-auto todo: use portal to handle long list
return (
<div className='space-y-1 rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg' style={{
@ -57,6 +61,8 @@ const VarReferencePopup: FC<Props> = ({
onChange={onChange}
itemWidth={itemWidth}
isSupportFileVar={isSupportFileVar}
showManageInputField={showManageRagInputFields}
onManageInputField={() => setShowInputFieldDialog?.(true)}
/>
}
</div >

View File

@ -24,6 +24,7 @@ import { FILE_STRUCT } from '@/app/components/workflow/constants'
import { Loop } from '@/app/components/base/icons/src/vender/workflow'
import { noop } from 'lodash-es'
import { InputField } from '@/app/components/base/icons/src/vender/pipeline'
import ManageInputField from './manage-input-field'
type ObjectChildrenProps = {
nodeId: string
@ -266,6 +267,8 @@ type Props = {
maxHeightClass?: string
onClose?: () => void
onBlur?: () => void
showManageInputField?: boolean
onManageInputField?: () => void
}
const VarReferenceVars: FC<Props> = ({
hideSearch,
@ -277,6 +280,8 @@ const VarReferenceVars: FC<Props> = ({
maxHeightClass,
onClose,
onBlur,
showManageInputField,
onManageInputField,
}) => {
const { t } = useTranslation()
const [searchText, setSearchText] = useState('')
@ -367,6 +372,13 @@ const VarReferenceVars: FC<Props> = ({
}
</div>
: <div className='pl-3 text-xs font-medium uppercase leading-[18px] text-gray-500'>{t('workflow.common.noVar')}</div>}
{
showManageInputField && (
<ManageInputField
onManage={onManageInputField || noop}
/>
)
}
</>
)
}

View File

@ -23,6 +23,8 @@ const ConditionInput = ({
}: ConditionInputProps) => {
const { t } = useTranslation()
const controlPromptEditorRerenderKey = useStore(s => s.controlPromptEditorRerenderKey)
const pipelineId = useStore(s => s.pipelineId)
const setShowInputFieldDialog = useStore(s => s.setShowInputFieldDialog)
return (
<PromptEditor
@ -49,6 +51,8 @@ const ConditionInput = ({
}
return acc
}, {} as any),
showManageInputField: !!pipelineId,
onManageInputField: () => setShowInputFieldDialog?.(true),
}}
onChange={onChange}
editable={!disabled}

View File

@ -13,7 +13,7 @@ const nodeDefault: NodeDefault<KnowledgeBaseNodeType> = {
index_chunk_variable_selector: [],
keyword_number: 10,
retrieval_model: {
top_k: 2,
top_k: 3,
score_threshold_enabled: false,
score_threshold: 0.5,
},

View File

@ -20,6 +20,8 @@ const ConditionInput = ({
}: ConditionInputProps) => {
const { t } = useTranslation()
const controlPromptEditorRerenderKey = useStore(s => s.controlPromptEditorRerenderKey)
const pipelineId = useStore(s => s.pipelineId)
const setShowInputFieldDialog = useStore(s => s.setShowInputFieldDialog)
return (
<PromptEditor
@ -43,6 +45,8 @@ const ConditionInput = ({
}
return acc
}, {} as any),
showManageInputField: !!pipelineId,
onManageInputField: () => setShowInputFieldDialog?.(true),
}}
onChange={onChange}
editable={!disabled}

View File

@ -11,6 +11,10 @@ const translation = {
descriptionPlaceholder: 'Please enter the description of this Knowledge Pipeline. (Optional) ',
},
},
inputField: {
create: 'Create user input field',
manage: 'Manage',
},
}
export default translation

View File

@ -11,6 +11,10 @@ const translation = {
descriptionPlaceholder: '请输入此 Pipeline 的描述。 (可选)',
},
},
inputField: {
create: '创建用户输入字段',
manage: '管理',
},
}
export default translation

View File

@ -127,7 +127,7 @@ export const useCheckPipelineDependencies = (
return useMutation({
mutationKey: [NAME_SPACE, 'check-dependencies'],
mutationFn: (pipelineId: string) => {
return post<PipelineCheckDependenciesResponse>(`/rag/pipelines/imports/${pipelineId}/check-dependencies`)
return get<PipelineCheckDependenciesResponse>(`/rag/pipelines/imports/${pipelineId}/check-dependencies`)
},
...mutationOptions,
})