mirror of
https://github.com/langgenius/dify.git
synced 2026-05-02 00:18:03 +08:00
Merge branch 'feat/queue-based-graph-engine' into feat/rag-2
# Conflicts: # api/core/memory/token_buffer_memory.py # api/core/rag/extractor/notion_extractor.py # api/core/repositories/sqlalchemy_workflow_node_execution_repository.py # api/core/variables/variables.py # api/core/workflow/graph/graph.py # api/core/workflow/graph_engine/entities/event.py # api/services/dataset_service.py # web/app/components/app-sidebar/index.tsx # web/app/components/base/tag-management/selector.tsx # web/app/components/base/toast/index.tsx # web/app/components/datasets/create/website/index.tsx # web/app/components/datasets/create/website/jina-reader/base/options-wrap.tsx # web/app/components/workflow/header/version-history-button.tsx # web/app/components/workflow/hooks/use-inspect-vars-crud-common.ts # web/app/components/workflow/hooks/use-workflow-interactions.ts # web/app/components/workflow/panel/version-history-panel/index.tsx # web/service/base.ts
This commit is contained in:
@ -64,7 +64,7 @@ const AddVariablePopupWithPosition = ({
|
||||
} as any,
|
||||
],
|
||||
hideEnv: true,
|
||||
hideChatVar: true,
|
||||
hideChatVar: !isChatMode,
|
||||
isChatMode,
|
||||
filterVar: filterVar(outputType as VarType),
|
||||
})
|
||||
|
||||
@ -93,7 +93,7 @@ export type AgentStrategySelectorProps = {
|
||||
}
|
||||
|
||||
export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => {
|
||||
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { enable_marketplace } = useGlobalPublicStore(s => s.systemFeatures)
|
||||
|
||||
const { value, onChange, canChooseMCPTool } = props
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
@ -236,7 +236,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
|
||||
'zh-Hans': '/guides/workflow/node/agent#选择-agent-策略',
|
||||
'ja-JP': '/guides/workflow/node/agent#エージェント戦略の選択',
|
||||
})}
|
||||
className='text-text-accent-secondary' target='_blank'>
|
||||
className='text-text-accent-secondary' target='_blank'>
|
||||
{t('workflow.nodes.agent.learnMore')}
|
||||
</Link>
|
||||
</div>}
|
||||
|
||||
@ -38,7 +38,7 @@ const Field: FC<Props> = ({
|
||||
<div className={cn(className, inline && 'flex w-full items-center justify-between')}>
|
||||
<div
|
||||
onClick={() => supportFold && toggleFold()}
|
||||
className={cn('sticky top-0 z-10 flex items-center justify-between bg-components-panel-bg', supportFold && 'cursor-pointer')}>
|
||||
className={cn('sticky top-0 flex items-center justify-between bg-components-panel-bg', 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} {required && <span className='text-text-destructive'>*</span>}
|
||||
|
||||
@ -11,7 +11,7 @@ const McpToolNotSupportTooltip: FC = () => {
|
||||
<Tooltip
|
||||
popupContent={
|
||||
<div className='w-[256px]'>
|
||||
{t('plugin.detailPanel.toolSelector.unsupportedMCPTool')}
|
||||
{t('plugin.detailPanel.toolSelector.unsupportedMCPTool')}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import { varHighlightHTML } from '@/app/components/app/configuration/base/var-highlight'
|
||||
import VarHighlight from '@/app/components/app/configuration/base/var-highlight'
|
||||
type Props = {
|
||||
isFocus?: boolean
|
||||
onFocus?: () => void
|
||||
@ -22,11 +22,24 @@ const SupportVarInput: FC<Props> = ({
|
||||
textClassName,
|
||||
readonly,
|
||||
}) => {
|
||||
const withHightContent = (value || '')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/\{\{([^}]+)\}\}/g, varHighlightHTML({ name: '$1', className: '!mb-0' })) // `<span class="${highLightClassName}">{{$1}}</span>`
|
||||
.replace(/\n/g, '<br />')
|
||||
const renderSafeContent = (inputValue: string) => {
|
||||
const parts = inputValue.split(/(\{\{[^}]+\}\}|\n)/g)
|
||||
return parts.map((part, index) => {
|
||||
const variableMatch = part.match(/^\{\{([^}]+)\}\}$/)
|
||||
if (variableMatch) {
|
||||
return (
|
||||
<VarHighlight
|
||||
key={`var-${index}`}
|
||||
name={variableMatch[1]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
if (part === '\n')
|
||||
return <br key={`br-${index}`} />
|
||||
|
||||
return <span key={`text-${index}`}>{part}</span>
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -42,9 +55,9 @@ const SupportVarInput: FC<Props> = ({
|
||||
<div
|
||||
className={cn(textClassName, 'h-full w-0 grow truncate whitespace-nowrap')}
|
||||
title={value}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: withHightContent,
|
||||
}}></div>
|
||||
>
|
||||
{renderSafeContent(value || '')}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -55,11 +55,11 @@ const VarList: FC<Props> = ({
|
||||
const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true)
|
||||
if (!isValid) {
|
||||
setToastHandle(Toast.notify({
|
||||
type: 'error',
|
||||
message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: errorKey }),
|
||||
}))
|
||||
return
|
||||
}
|
||||
type: 'error',
|
||||
message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: errorKey }),
|
||||
}))
|
||||
return
|
||||
}
|
||||
if (list.some(item => item.variable?.trim() === newKey.trim())) {
|
||||
console.log('new key', newKey.trim())
|
||||
setToastHandle(Toast.notify({
|
||||
|
||||
@ -82,11 +82,11 @@ const LastRun: FC<Props> = ({
|
||||
}, [nodeId])
|
||||
|
||||
const handlePageVisibilityChange = useCallback(() => {
|
||||
if (document.visibilityState === 'hidden')
|
||||
setPageHasHide(true)
|
||||
else
|
||||
setPageShowed(true)
|
||||
}, [])
|
||||
if (document.visibilityState === 'hidden')
|
||||
setPageHasHide(true)
|
||||
else
|
||||
setPageShowed(true)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
document.addEventListener('visibilitychange', handlePageVisibilityChange)
|
||||
|
||||
|
||||
@ -118,8 +118,8 @@ function useOutputVarList<T>({
|
||||
const [removedVar, setRemovedVar] = useState<ValueSelector>([])
|
||||
const removeVarInNode = useCallback(() => {
|
||||
const varId = nodesWithInspectVars.find(node => node.nodeId === id)?.vars.find((varItem) => {
|
||||
return varItem.name === removedVar[1]
|
||||
})?.id
|
||||
return varItem.name === removedVar[1]
|
||||
})?.id
|
||||
if(varId)
|
||||
deleteInspectVar(id, varId)
|
||||
removeUsedVarInNodes(removedVar)
|
||||
@ -143,8 +143,8 @@ function useOutputVarList<T>({
|
||||
setInputs(newInputs)
|
||||
onOutputKeyOrdersChange(outputKeyOrders.filter((_, i) => i !== index))
|
||||
const varId = nodesWithInspectVars.find(node => node.nodeId === id)?.vars.find((varItem) => {
|
||||
return varItem.name === key
|
||||
})?.id
|
||||
return varItem.name === key
|
||||
})?.id
|
||||
if(varId)
|
||||
deleteInspectVar(id, varId)
|
||||
}, [outputKeyOrders, isVarUsedInNodes, id, inputs, setInputs, onOutputKeyOrdersChange, nodesWithInspectVars, deleteInspectVar, showRemoveVarConfirm, varKey])
|
||||
|
||||
@ -45,10 +45,10 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
||||
const resetEditor = useStore(s => s.setControlPromptEditorRerenderKey)
|
||||
return <div className='my-2'>
|
||||
<Field
|
||||
required
|
||||
title={t('workflow.nodes.agent.strategy.label')}
|
||||
className='px-4 py-2'
|
||||
tooltip={t('workflow.nodes.agent.strategy.tooltip')} >
|
||||
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!,
|
||||
|
||||
@ -76,7 +76,7 @@ const useSingleRunFormParams = ({
|
||||
return formatTracing([runResult], t)[0]
|
||||
}, [runResult, t])
|
||||
|
||||
const getDependentVars = () => {
|
||||
const getDependentVars = () => {
|
||||
return varInputs.map((item) => {
|
||||
// Guard against null/undefined variable to prevent app crash
|
||||
if (!item.variable || typeof item.variable !== 'string')
|
||||
|
||||
@ -69,7 +69,7 @@ const VarList: FC<Props> = ({
|
||||
if (item.value === WriteMode.set || item.value === WriteMode.increment || item.value === WriteMode.decrement
|
||||
|| item.value === WriteMode.multiply || item.value === WriteMode.divide) {
|
||||
if(varType === VarType.boolean)
|
||||
draft[index].value = false
|
||||
draft[index].value = false
|
||||
draft[index].input_type = AssignerNodeInputType.constant
|
||||
}
|
||||
else {
|
||||
|
||||
@ -31,8 +31,6 @@ const useKeyValueList = (value: string, onChange: (value: string) => void, noFil
|
||||
const newValue = list.filter(item => item.key && item.value).map(item => `${item.key}:${item.value}`).join('\n')
|
||||
if (newValue !== value)
|
||||
onChange(newValue)
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [list, noFilter])
|
||||
const addItem = useCallback(() => {
|
||||
setList([...list, {
|
||||
|
||||
@ -51,7 +51,6 @@ const useConfig = (id: string, payload: HttpNodeType) => {
|
||||
setInputs(newInputs)
|
||||
setIsDataReady(true)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [defaultConfig])
|
||||
|
||||
const handleMethodChange = useCallback((method: Method) => {
|
||||
|
||||
@ -31,7 +31,6 @@ const MetadataTrigger = ({
|
||||
handleRemoveCondition(condition.id)
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [metadataList, handleRemoveCondition, selectedDatasetsLoaded])
|
||||
|
||||
return (
|
||||
|
||||
@ -172,7 +172,6 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
|
||||
}
|
||||
})
|
||||
setInputs(newInput)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [currentProvider?.provider, currentModel, currentRerankModel, rerankDefaultModel])
|
||||
const [selectedDatasets, setSelectedDatasets] = useState<DataSet[]>([])
|
||||
const [rerankModelOpen, setRerankModelOpen] = useState(false)
|
||||
@ -229,7 +228,6 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
|
||||
setInputs(newInputs)
|
||||
setSelectedDatasetsLoaded(true)
|
||||
})()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
@ -241,7 +239,6 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
|
||||
setInputs(produce(inputs, (draft) => {
|
||||
draft.query_variable_selector = query_variable_selector
|
||||
}))
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const handleOnDatasetsChange = useCallback((newDatasets: DataSet[]) => {
|
||||
|
||||
@ -34,7 +34,6 @@ const JsonImporter: FC<JsonImporterProps> = ({
|
||||
const rect = importBtnRef.current.getBoundingClientRect()
|
||||
updateBtnWidth(rect.width)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const handleTrigger = useCallback((e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
|
||||
@ -140,7 +140,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
|
||||
<ConfigPrompt
|
||||
readOnly={readOnly}
|
||||
nodeId={id}
|
||||
filterVar={filterInputVar}
|
||||
filterVar={isShowVars ? filterJinja2InputVar : filterInputVar}
|
||||
isChatModel={isChatModel}
|
||||
isChatApp={isChatMode}
|
||||
isShowContext
|
||||
|
||||
@ -308,7 +308,7 @@ const useConfig = (id: string, payload: LLMNodeType) => {
|
||||
}, [])
|
||||
|
||||
const filterJinja2InputVar = useCallback((varPayload: Var) => {
|
||||
return [VarType.number, VarType.string, VarType.secret, VarType.arrayString, VarType.arrayNumber].includes(varPayload.type)
|
||||
return [VarType.number, VarType.string, VarType.secret, VarType.arrayString, VarType.arrayNumber, VarType.arrayBoolean, VarType.arrayObject, VarType.object, VarType.array, VarType.boolean].includes(varPayload.type)
|
||||
}, [])
|
||||
|
||||
const filterMemoryPromptVar = useCallback((varPayload: Var) => {
|
||||
|
||||
@ -155,7 +155,6 @@ const useConfig = (id: string, payload: ParameterExtractorNodeType) => {
|
||||
return
|
||||
setModelChanged(false)
|
||||
handleVisionConfigAfterModelChanged()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isVisionModel, modelChanged])
|
||||
|
||||
const {
|
||||
|
||||
@ -84,10 +84,10 @@ const ClassList: FC<Props> = ({
|
||||
})()
|
||||
return (
|
||||
<div key={item.id}
|
||||
className={cn(
|
||||
'group relative rounded-[10px] bg-components-panel-bg',
|
||||
`-ml-${handleSideWidth} min-h-[40px] px-0 py-0`,
|
||||
)}>
|
||||
className={cn(
|
||||
'group relative rounded-[10px] bg-components-panel-bg',
|
||||
`-ml-${handleSideWidth} min-h-[40px] px-0 py-0`,
|
||||
)}>
|
||||
<div >
|
||||
<Item
|
||||
className={cn(canDrag && 'handle')}
|
||||
|
||||
@ -88,7 +88,6 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => {
|
||||
return
|
||||
setModelChanged(false)
|
||||
handleVisionConfigAfterModelChanged()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isVisionModel, modelChanged])
|
||||
|
||||
const handleQueryVarChange = useCallback((newVar: ValueSelector | string) => {
|
||||
@ -110,7 +109,6 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => {
|
||||
query_variable_selector: inputs.query_variable_selector.length > 0 ? inputs.query_variable_selector : query_variable_selector,
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [defaultConfig])
|
||||
|
||||
const handleClassesChange = useCallback((newClasses: any) => {
|
||||
|
||||
@ -61,7 +61,7 @@ const useSingleRunFormParams = ({
|
||||
Object.keys(inputs.tool_parameters).forEach((key: string) => {
|
||||
const { type, value } = inputs.tool_parameters[key]
|
||||
if (type === VarType.constant && (value === undefined || value === null)) {
|
||||
if(!draft.tool_parameters || !draft.tool_parameters[key])
|
||||
if(!draft.tool_parameters || !draft.tool_parameters[key])
|
||||
return
|
||||
draft[key] = value
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user