mirror of
https://github.com/langgenius/dify.git
synced 2026-04-21 11:17:38 +08:00
Merge branch 'main' into feat/rag-pipeline
This commit is contained in:
@ -316,6 +316,7 @@ export const Workflow: FC<WorkflowProps> = memo(({
|
||||
nodesConnectable={!nodesReadOnly}
|
||||
nodesFocusable={!nodesReadOnly}
|
||||
edgesFocusable={!nodesReadOnly}
|
||||
panOnScroll
|
||||
panOnDrag={controlMode === ControlMode.Hand && !workflowReadOnly}
|
||||
zoomOnPinch={!workflowReadOnly}
|
||||
zoomOnScroll={!workflowReadOnly}
|
||||
|
||||
@ -17,6 +17,7 @@ type Props = {
|
||||
children?: React.JSX.Element | string | null
|
||||
operations?: React.JSX.Element
|
||||
inline?: boolean
|
||||
required?: boolean
|
||||
}
|
||||
|
||||
const Field: FC<Props> = ({
|
||||
@ -28,6 +29,7 @@ const Field: FC<Props> = ({
|
||||
operations,
|
||||
inline,
|
||||
supportFold,
|
||||
required,
|
||||
}) => {
|
||||
const [fold, {
|
||||
toggle: toggleFold,
|
||||
@ -38,7 +40,9 @@ const Field: FC<Props> = ({
|
||||
onClick={() => supportFold && toggleFold()}
|
||||
className={cn('flex items-center justify-between', supportFold && 'cursor-pointer')}>
|
||||
<div className='flex h-6 items-center'>
|
||||
<div className={cn(isSubTitle ? 'system-xs-medium-uppercase text-text-tertiary' : 'system-sm-semibold-uppercase text-text-secondary')}>{title}</div>
|
||||
<div className={cn(isSubTitle ? 'system-xs-medium-uppercase text-text-tertiary' : 'system-sm-semibold-uppercase text-text-secondary')}>
|
||||
{title} {required && <span className='text-text-destructive'>*</span>}
|
||||
</div>
|
||||
{tooltip && (
|
||||
<Tooltip
|
||||
popupContent={tooltip}
|
||||
|
||||
@ -596,17 +596,16 @@ const getIterationItemType = ({
|
||||
arrayType = curr.find((v: any) => v.variable === (valueSelector).join('.'))?.type
|
||||
}
|
||||
else {
|
||||
(valueSelector).slice(1).forEach((key, i) => {
|
||||
for (let i = 1; i < valueSelector.length - 1; i++) {
|
||||
const key = valueSelector[i]
|
||||
const isLast = i === valueSelector.length - 2
|
||||
curr = curr?.find((v: any) => v.variable === key)
|
||||
if (isLast) {
|
||||
arrayType = curr?.type
|
||||
}
|
||||
else {
|
||||
if (curr?.type === VarType.object || curr?.type === VarType.file)
|
||||
curr = curr.children
|
||||
}
|
||||
})
|
||||
curr = Array.isArray(curr) ? curr.find(v => v.variable === key) : []
|
||||
|
||||
if (isLast)
|
||||
arrayType = curr?.type
|
||||
else if (curr?.type === VarType.object || curr?.type === VarType.file)
|
||||
curr = curr.children || []
|
||||
}
|
||||
}
|
||||
|
||||
switch (arrayType as VarType) {
|
||||
@ -631,7 +630,7 @@ const getLoopItemType = ({
|
||||
}: {
|
||||
valueSelector: ValueSelector
|
||||
beforeNodesOutputVars: NodeOutPutVar[]
|
||||
// eslint-disable-next-line sonarjs/no-identical-functions
|
||||
|
||||
}): VarType => {
|
||||
const outputVarNodeId = valueSelector[0]
|
||||
const isSystem = isSystemVar(valueSelector)
|
||||
|
||||
@ -81,7 +81,11 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
||||
const resetEditor = useStore(s => s.setControlPromptEditorRerenderKey)
|
||||
|
||||
return <div className='my-2'>
|
||||
<Field title={t('workflow.nodes.agent.strategy.label')} className='px-4 py-2' tooltip={t('workflow.nodes.agent.strategy.tooltip')} >
|
||||
<Field
|
||||
required
|
||||
title={t('workflow.nodes.agent.strategy.label')}
|
||||
className='px-4 py-2'
|
||||
tooltip={t('workflow.nodes.agent.strategy.tooltip')} >
|
||||
<AgentStrategy
|
||||
strategy={inputs.agent_strategy_name ? {
|
||||
agent_strategy_provider_name: inputs.agent_strategy_provider_name!,
|
||||
|
||||
@ -117,8 +117,8 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({
|
||||
operations={
|
||||
<AddButton onClick={handleAddOutputVariable} />
|
||||
}
|
||||
required
|
||||
>
|
||||
|
||||
<OutputVarList
|
||||
readonly={readOnly}
|
||||
outputs={inputs.outputs}
|
||||
|
||||
@ -64,6 +64,7 @@ const Panel: FC<NodePanelProps<DocExtractorNodeType>> = ({
|
||||
<div className='space-y-4 px-4 pb-4'>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.inputVar`)}
|
||||
required
|
||||
>
|
||||
<>
|
||||
<VarReferencePicker
|
||||
|
||||
@ -69,6 +69,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
|
||||
<div className='space-y-4 px-4 pb-4'>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.api`)}
|
||||
required
|
||||
operations={
|
||||
<div className='flex'>
|
||||
<div
|
||||
@ -126,6 +127,7 @@ const Panel: FC<NodePanelProps<HttpNodeType>> = ({
|
||||
</Field>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.body`)}
|
||||
required
|
||||
>
|
||||
<EditBody
|
||||
nodeId={id}
|
||||
|
||||
@ -73,6 +73,7 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
|
||||
<div className='space-y-4 px-4 pb-4'>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.input`)}
|
||||
required
|
||||
operations={(
|
||||
<div className='system-2xs-medium-uppercase flex h-[18px] items-center rounded-[5px] border border-divider-deep px-1 capitalize text-text-tertiary'>Array</div>
|
||||
)}
|
||||
@ -91,6 +92,7 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
|
||||
<div className='mt-2 space-y-4 px-4 pb-4'>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.output`)}
|
||||
required
|
||||
operations={(
|
||||
<div className='system-2xs-medium-uppercase flex h-[18px] items-center rounded-[5px] border border-divider-deep px-1 capitalize text-text-tertiary'>Array</div>
|
||||
)}
|
||||
|
||||
@ -81,6 +81,7 @@ const Panel: FC<NodePanelProps<KnowledgeRetrievalNodeType>> = ({
|
||||
{/* {JSON.stringify(inputs, null, 2)} */}
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.queryVariable`)}
|
||||
required
|
||||
>
|
||||
<VarReferencePicker
|
||||
nodeId={id}
|
||||
@ -94,6 +95,7 @@ const Panel: FC<NodePanelProps<KnowledgeRetrievalNodeType>> = ({
|
||||
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.knowledge`)}
|
||||
required
|
||||
operations={
|
||||
<div className='flex items-center space-x-1'>
|
||||
<RetrievalConfig
|
||||
|
||||
@ -46,6 +46,7 @@ const Panel: FC<NodePanelProps<ListFilterNodeType>> = ({
|
||||
<div className='space-y-4 px-4'>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.inputVar`)}
|
||||
required
|
||||
>
|
||||
<VarReferencePicker
|
||||
readonly={readOnly}
|
||||
|
||||
@ -147,6 +147,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
|
||||
<div className='space-y-4 px-4 pb-4'>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.model`)}
|
||||
required
|
||||
>
|
||||
<ModelParameterModal
|
||||
popupClassName='!w-[387px]'
|
||||
@ -295,7 +296,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
|
||||
onCollapse={setStructuredOutputCollapsed}
|
||||
operations={
|
||||
<div className='mr-4 flex shrink-0 items-center'>
|
||||
{!isModelSupportStructuredOutput && (
|
||||
{(!isModelSupportStructuredOutput && !!inputs.structured_output_enabled) && (
|
||||
<Tooltip noDecoration popupContent={
|
||||
<div className='w-[232px] rounded-xl border-[0.5px] border-components-panel-border bg-components-tooltip-bg px-4 py-3.5 shadow-lg backdrop-blur-[5px]'>
|
||||
<div className='title-xs-semi-bold text-text-primary'>{t('app.structOutput.modelNotSupported')}</div>
|
||||
|
||||
@ -115,6 +115,7 @@ const Panel: FC<NodePanelProps<ParameterExtractorNodeType>> = ({
|
||||
<div className='space-y-4 px-4'>
|
||||
<Field
|
||||
title={t(`${i18nCommonPrefix}.model`)}
|
||||
required
|
||||
>
|
||||
<ModelParameterModal
|
||||
popupClassName='!w-[387px]'
|
||||
@ -133,6 +134,7 @@ const Panel: FC<NodePanelProps<ParameterExtractorNodeType>> = ({
|
||||
</Field>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.inputVar`)}
|
||||
required
|
||||
>
|
||||
<>
|
||||
<VarReferencePicker
|
||||
@ -157,6 +159,7 @@ const Panel: FC<NodePanelProps<ParameterExtractorNodeType>> = ({
|
||||
/>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.extractParameters`)}
|
||||
required
|
||||
operations={
|
||||
!readOnly
|
||||
? (
|
||||
|
||||
@ -63,7 +63,7 @@ const ClassList: FC<Props> = ({
|
||||
return (
|
||||
<Item
|
||||
nodeId={nodeId}
|
||||
key={index}
|
||||
key={list[index].id}
|
||||
payload={item}
|
||||
onChange={handleClassChange(index)}
|
||||
onRemove={handleRemoveClass(index)}
|
||||
|
||||
@ -103,6 +103,7 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({
|
||||
<div className='space-y-4 px-4'>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.model`)}
|
||||
required
|
||||
>
|
||||
<ModelParameterModal
|
||||
popupClassName='!w-[387px]'
|
||||
@ -121,6 +122,7 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({
|
||||
</Field>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.inputVars`)}
|
||||
required
|
||||
>
|
||||
<VarReferencePicker
|
||||
readonly={readOnly}
|
||||
@ -143,6 +145,7 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({
|
||||
/>
|
||||
<Field
|
||||
title={t(`${i18nPrefix}.class`)}
|
||||
required
|
||||
>
|
||||
<ClassList
|
||||
nodeId={id}
|
||||
|
||||
@ -47,8 +47,14 @@ const VariableModal = ({
|
||||
return
|
||||
if (!value)
|
||||
return notify({ type: 'error', message: 'value can not be empty' })
|
||||
if (!env && envList.some(env => env.name === name))
|
||||
|
||||
// Add check for duplicate name when editing
|
||||
if (env && env.name !== name && envList.some(e => e.name === name))
|
||||
return notify({ type: 'error', message: 'name is existed' })
|
||||
// Original check for create new variable
|
||||
if (!env && envList.some(e => e.name === name))
|
||||
return notify({ type: 'error', message: 'name is existed' })
|
||||
|
||||
onSave({
|
||||
id: env ? env.id : uuid4(),
|
||||
value_type: type,
|
||||
|
||||
Reference in New Issue
Block a user