Merge branch 'main' into feat/rag-pipeline

This commit is contained in:
zxhlyh
2025-04-29 16:27:49 +08:00
279 changed files with 4905 additions and 859 deletions

View File

@ -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}

View File

@ -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}

View File

@ -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)

View File

@ -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!,

View File

@ -117,8 +117,8 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({
operations={
<AddButton onClick={handleAddOutputVariable} />
}
required
>
<OutputVarList
readonly={readOnly}
outputs={inputs.outputs}

View File

@ -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

View File

@ -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}

View File

@ -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>
)}

View File

@ -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

View File

@ -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}

View File

@ -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>

View File

@ -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
? (

View File

@ -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)}

View File

@ -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}

View File

@ -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,