mirror of
https://github.com/langgenius/dify.git
synced 2025-12-25 01:00:42 -05:00
feat: knowledge pipeline (#25360)
Signed-off-by: -LAN- <laipz8200@outlook.com> Co-authored-by: twwu <twwu@dify.ai> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: jyong <718720800@qq.com> Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com> Co-authored-by: lyzno1 <yuanyouhuilyz@gmail.com> Co-authored-by: quicksand <quicksandzn@gmail.com> Co-authored-by: Jyong <76649700+JohnJyong@users.noreply.github.com> Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: Yongtao Huang <yongtaoh2022@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: nite-knite <nkCoding@gmail.com> Co-authored-by: Hanqing Zhao <sherry9277@gmail.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Harry <xh001x@hotmail.com>
This commit is contained in:
@@ -34,7 +34,7 @@ import {
|
||||
import type { FileEntity } from '@/app/components/base/file-uploader/types'
|
||||
import { getThreadMessages } from '@/app/components/base/chat/utils'
|
||||
import { useInvalidAllLastRun } from '@/service/use-workflow'
|
||||
import { useParams } from 'next/navigation'
|
||||
import { useHooksStore } from '../../hooks-store'
|
||||
|
||||
type GetAbortController = (abortController: AbortController) => void
|
||||
type SendCallback = {
|
||||
@@ -58,8 +58,8 @@ export const useChat = (
|
||||
const taskIdRef = useRef('')
|
||||
const [isResponding, setIsResponding] = useState(false)
|
||||
const isRespondingRef = useRef(false)
|
||||
const { appId } = useParams()
|
||||
const invalidAllLastRun = useInvalidAllLastRun(appId as string)
|
||||
const configsMap = useHooksStore(s => s.configsMap)
|
||||
const invalidAllLastRun = useInvalidAllLastRun(configsMap?.flowType, configsMap?.flowId)
|
||||
const { fetchInspectVars } = useSetWorkflowVarsWithValue()
|
||||
const [suggestedQuestions, setSuggestQuestions] = useState<string[]>([])
|
||||
const suggestedQuestionsAbortControllerRef = useRef<AbortController | null>(null)
|
||||
@@ -296,7 +296,7 @@ export const useChat = (
|
||||
},
|
||||
async onCompleted(hasError?: boolean, errorMessage?: string) {
|
||||
handleResponding(false)
|
||||
fetchInspectVars()
|
||||
fetchInspectVars({})
|
||||
invalidAllLastRun()
|
||||
|
||||
if (hasError) {
|
||||
@@ -466,7 +466,7 @@ export const useChat = (
|
||||
|
||||
if (current.execution_metadata) {
|
||||
if (current.execution_metadata.agent_log) {
|
||||
const currentLogIndex = current.execution_metadata.agent_log.findIndex(log => log.id === data.id)
|
||||
const currentLogIndex = current.execution_metadata.agent_log.findIndex(log => log.message_id === data.message_id)
|
||||
if (currentLogIndex > -1) {
|
||||
current.execution_metadata.agent_log[currentLogIndex] = {
|
||||
...current.execution_metadata.agent_log[currentLogIndex],
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
import type { FC } from 'react'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { memo, useCallback, useEffect, useRef } from 'react'
|
||||
import type { VersionHistoryPanelProps } from '@/app/components/workflow/panel/version-history-panel'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import { useStore as useReactflow } from 'reactflow'
|
||||
import { Panel as NodePanel } from '../nodes'
|
||||
import { useStore } from '../store'
|
||||
import EnvPanel from './env-panel'
|
||||
import cn from '@/utils/classnames'
|
||||
import dynamic from 'next/dynamic'
|
||||
|
||||
const VersionHistoryPanel = dynamic(() => import('@/app/components/workflow/panel/version-history-panel'), {
|
||||
ssr: false,
|
||||
})
|
||||
|
||||
export type PanelProps = {
|
||||
components?: {
|
||||
left?: React.ReactNode
|
||||
right?: React.ReactNode
|
||||
}
|
||||
versionHistoryPanelProps?: VersionHistoryPanelProps
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +67,7 @@ const useResizeObserver = (
|
||||
|
||||
const Panel: FC<PanelProps> = ({
|
||||
components,
|
||||
versionHistoryPanelProps,
|
||||
}) => {
|
||||
const selectedNode = useReactflow(useShallow((s) => {
|
||||
const nodes = s.getNodes()
|
||||
@@ -127,8 +135,19 @@ const Panel: FC<PanelProps> = ({
|
||||
className="relative"
|
||||
ref={otherPanelRef}
|
||||
>
|
||||
{components?.right}
|
||||
{showEnvPanel && <EnvPanel />}
|
||||
{
|
||||
components?.right
|
||||
}
|
||||
{
|
||||
showWorkflowVersionHistoryPanel && (
|
||||
<VersionHistoryPanel {...versionHistoryPanelProps} />
|
||||
)
|
||||
}
|
||||
{
|
||||
showEnvPanel && (
|
||||
<EnvPanel />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -19,11 +19,11 @@ import { useWorkflowRun } from '../hooks'
|
||||
import type { StartNodeType } from '../nodes/start/types'
|
||||
import { TransferMethod } from '../../base/text-generation/types'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { useFeatures } from '@/app/components/base/features/hooks'
|
||||
import {
|
||||
getProcessedInputs,
|
||||
} from '@/app/components/base/chat/chat/utils'
|
||||
import { useCheckInputsForms } from '@/app/components/base/chat/chat/check-input-forms-hooks'
|
||||
import { useHooksStore } from '../hooks-store'
|
||||
|
||||
type Props = {
|
||||
onRun: () => void
|
||||
@@ -36,7 +36,7 @@ const InputsPanel = ({ onRun }: Props) => {
|
||||
inputs: s.inputs,
|
||||
setInputs: s.setInputs,
|
||||
}))
|
||||
const fileSettings = useFeatures(s => s.features.file)
|
||||
const fileSettings = useHooksStore(s => s.configsMap?.fileSettings)
|
||||
const nodes = useNodes<StartNodeType>()
|
||||
const files = useStore(s => s.files)
|
||||
const workflowRunningData = useStore(s => s.workflowRunningData)
|
||||
|
||||
@@ -3,11 +3,13 @@ import type { WorkflowRunDetailResponse } from '@/models/log'
|
||||
import Run from '../run'
|
||||
import { useStore } from '../store'
|
||||
import { useWorkflowUpdate } from '../hooks'
|
||||
import { useHooksStore } from '../hooks-store'
|
||||
import { formatWorkflowRunIdentifier } from '../utils'
|
||||
|
||||
const Record = () => {
|
||||
const historyWorkflowData = useStore(s => s.historyWorkflowData)
|
||||
const { handleUpdateWorkflowCanvas } = useWorkflowUpdate()
|
||||
const getWorkflowRunAndTraceUrl = useHooksStore(s => s.getWorkflowRunAndTraceUrl)
|
||||
|
||||
const handleResultCallback = useCallback((res: WorkflowRunDetailResponse) => {
|
||||
const graph = res.graph
|
||||
@@ -24,7 +26,8 @@ const Record = () => {
|
||||
{`Test Run${formatWorkflowRunIdentifier(historyWorkflowData?.finished_at)}`}
|
||||
</div>
|
||||
<Run
|
||||
runID={historyWorkflowData?.id || ''}
|
||||
runDetailUrl={getWorkflowRunAndTraceUrl(historyWorkflowData?.id).runUrl}
|
||||
tracingListUrl={getWorkflowRunAndTraceUrl(historyWorkflowData?.id).traceUrl}
|
||||
getResultCallback={handleResultCallback}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -2,12 +2,14 @@ import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { VersionHistoryContextMenuOptions } from '../../../types'
|
||||
import type { ContextMenuProps } from './index'
|
||||
import { useStore } from '@/app/components/workflow/store'
|
||||
|
||||
const useContextMenu = (props: ContextMenuProps) => {
|
||||
const {
|
||||
isNamedVersion,
|
||||
} = props
|
||||
const { t } = useTranslation()
|
||||
const pipelineId = useStore(s => s.pipelineId)
|
||||
|
||||
const deleteOperation = {
|
||||
key: VersionHistoryContextMenuOptions.delete,
|
||||
@@ -29,10 +31,11 @@ const useContextMenu = (props: ContextMenuProps) => {
|
||||
key: VersionHistoryContextMenuOptions.edit,
|
||||
name: t('workflow.versionHistory.nameThisVersion'),
|
||||
},
|
||||
{
|
||||
// todo: pipeline support export specific version DSL
|
||||
...(!pipelineId ? [{
|
||||
key: VersionHistoryContextMenuOptions.exportDSL,
|
||||
name: t('app.export'),
|
||||
},
|
||||
}] : []),
|
||||
{
|
||||
key: VersionHistoryContextMenuOptions.copyId,
|
||||
name: t('workflow.versionHistory.copyId'),
|
||||
|
||||
@@ -9,7 +9,6 @@ import { VersionHistoryContextMenuOptions, WorkflowVersionFilterOptions } from '
|
||||
import VersionHistoryItem from './version-history-item'
|
||||
import Filter from './filter'
|
||||
import type { VersionHistory } from '@/types/workflow'
|
||||
import { useStore as useAppStore } from '@/app/components/app/store'
|
||||
import { useDeleteWorkflow, useInvalidAllLastRun, useResetWorkflowVersionHistory, useUpdateWorkflow, useWorkflowVersionHistory } from '@/service/use-workflow'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import Loading from './loading'
|
||||
@@ -19,11 +18,23 @@ import RestoreConfirmModal from './restore-confirm-modal'
|
||||
import DeleteConfirmModal from './delete-confirm-modal'
|
||||
import VersionInfoModal from '@/app/components/app/app-publisher/version-info-modal'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { useHooksStore } from '../../hooks-store'
|
||||
|
||||
const HISTORY_PER_PAGE = 10
|
||||
const INITIAL_PAGE = 1
|
||||
|
||||
const VersionHistoryPanel = () => {
|
||||
export type VersionHistoryPanelProps = {
|
||||
getVersionListUrl?: string
|
||||
deleteVersionUrl?: (versionId: string) => string
|
||||
updateVersionUrl?: (versionId: string) => string
|
||||
latestVersionId?: string
|
||||
}
|
||||
export const VersionHistoryPanel = ({
|
||||
getVersionListUrl,
|
||||
deleteVersionUrl,
|
||||
updateVersionUrl,
|
||||
latestVersionId,
|
||||
}: VersionHistoryPanelProps) => {
|
||||
const [filterValue, setFilterValue] = useState(WorkflowVersionFilterOptions.all)
|
||||
const [isOnlyShowNamedVersions, setIsOnlyShowNamedVersions] = useState(false)
|
||||
const [operatedItem, setOperatedItem] = useState<VersionHistory>()
|
||||
@@ -34,12 +45,12 @@ const VersionHistoryPanel = () => {
|
||||
const { handleSyncWorkflowDraft } = useNodesSyncDraft()
|
||||
const { handleRestoreFromPublishedWorkflow, handleLoadBackupDraft } = useWorkflowRun()
|
||||
const { handleExportDSL } = useDSL()
|
||||
const appDetail = useAppStore.getState().appDetail
|
||||
const setShowWorkflowVersionHistoryPanel = useStore(s => s.setShowWorkflowVersionHistoryPanel)
|
||||
const currentVersion = useStore(s => s.currentVersion)
|
||||
const setCurrentVersion = useStore(s => s.setCurrentVersion)
|
||||
const userProfile = useAppContextSelector(s => s.userProfile)
|
||||
const invalidAllLastRun = useInvalidAllLastRun(appDetail!.id)
|
||||
const configsMap = useHooksStore(s => s.configsMap)
|
||||
const invalidAllLastRun = useInvalidAllLastRun(configsMap?.flowType, configsMap?.flowId)
|
||||
const {
|
||||
deleteAllInspectVars,
|
||||
} = workflowStore.getState()
|
||||
@@ -51,7 +62,7 @@ const VersionHistoryPanel = () => {
|
||||
hasNextPage,
|
||||
isFetching,
|
||||
} = useWorkflowVersionHistory({
|
||||
appId: appDetail!.id,
|
||||
url: getVersionListUrl || '',
|
||||
initialPage: INITIAL_PAGE,
|
||||
limit: HISTORY_PER_PAGE,
|
||||
userId: filterValue === WorkflowVersionFilterOptions.onlyYours ? userProfile.id : '',
|
||||
@@ -109,7 +120,7 @@ const VersionHistoryPanel = () => {
|
||||
})
|
||||
break
|
||||
case VersionHistoryContextMenuOptions.exportDSL:
|
||||
handleExportDSL(false, item.id)
|
||||
handleExportDSL?.(false, item.id)
|
||||
break
|
||||
}
|
||||
}, [t, handleExportDSL])
|
||||
@@ -128,7 +139,7 @@ const VersionHistoryPanel = () => {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const resetWorkflowVersionHistory = useResetWorkflowVersionHistory(appDetail!.id)
|
||||
const resetWorkflowVersionHistory = useResetWorkflowVersionHistory()
|
||||
|
||||
const handleRestore = useCallback((item: VersionHistory) => {
|
||||
setShowWorkflowVersionHistoryPanel(false)
|
||||
@@ -156,10 +167,10 @@ const VersionHistoryPanel = () => {
|
||||
})
|
||||
}, [setShowWorkflowVersionHistoryPanel, handleRestoreFromPublishedWorkflow, workflowStore, handleSyncWorkflowDraft, deleteAllInspectVars, invalidAllLastRun, t, resetWorkflowVersionHistory])
|
||||
|
||||
const { mutateAsync: deleteWorkflow } = useDeleteWorkflow(appDetail!.id)
|
||||
const { mutateAsync: deleteWorkflow } = useDeleteWorkflow()
|
||||
|
||||
const handleDelete = useCallback(async (id: string) => {
|
||||
await deleteWorkflow(id, {
|
||||
await deleteWorkflow(deleteVersionUrl?.(id) || '', {
|
||||
onSuccess: () => {
|
||||
setDeleteConfirmOpen(false)
|
||||
Toast.notify({
|
||||
@@ -180,14 +191,14 @@ const VersionHistoryPanel = () => {
|
||||
setDeleteConfirmOpen(false)
|
||||
},
|
||||
})
|
||||
}, [deleteWorkflow, t, resetWorkflowVersionHistory, deleteAllInspectVars, invalidAllLastRun])
|
||||
}, [deleteWorkflow, t, resetWorkflowVersionHistory, deleteAllInspectVars, invalidAllLastRun, deleteVersionUrl])
|
||||
|
||||
const { mutateAsync: updateWorkflow } = useUpdateWorkflow(appDetail!.id)
|
||||
const { mutateAsync: updateWorkflow } = useUpdateWorkflow()
|
||||
|
||||
const handleUpdateWorkflow = useCallback(async (params: { id?: string, title: string, releaseNotes: string }) => {
|
||||
const { id, ...rest } = params
|
||||
await updateWorkflow({
|
||||
workflowId: id!,
|
||||
url: updateVersionUrl?.(id || '') || '',
|
||||
...rest,
|
||||
}, {
|
||||
onSuccess: () => {
|
||||
@@ -208,7 +219,7 @@ const VersionHistoryPanel = () => {
|
||||
setEditModalOpen(false)
|
||||
},
|
||||
})
|
||||
}, [t, updateWorkflow, resetWorkflowVersionHistory])
|
||||
}, [t, updateWorkflow, resetWorkflowVersionHistory, updateVersionUrl])
|
||||
|
||||
return (
|
||||
<div className='flex h-full w-[268px] flex-col rounded-l-2xl border-y-[0.5px] border-l-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5'>
|
||||
@@ -243,7 +254,7 @@ const VersionHistoryPanel = () => {
|
||||
key={item.id}
|
||||
item={item}
|
||||
currentVersion={currentVersion}
|
||||
latestVersionId={appDetail!.workflow!.id}
|
||||
latestVersionId={latestVersionId || ''}
|
||||
onClick={handleVersionClick}
|
||||
handleClickMenuItem={handleClickMenuItem.bind(null, item)}
|
||||
isLast={isLast}
|
||||
|
||||
@@ -184,7 +184,12 @@ const WorkflowPreview = () => {
|
||||
{currentTab === 'DETAIL' && (
|
||||
<ResultPanel
|
||||
inputs={workflowRunningData?.result?.inputs}
|
||||
inputs_truncated={workflowRunningData?.result?.inputs_truncated}
|
||||
process_data={workflowRunningData?.result?.process_data}
|
||||
process_data_truncated={workflowRunningData?.result?.process_data_truncated}
|
||||
outputs={workflowRunningData?.result?.outputs}
|
||||
outputs_truncated={workflowRunningData?.result?.outputs_truncated}
|
||||
outputs_full_content={workflowRunningData?.result?.outputs_full_content}
|
||||
status={workflowRunningData?.result?.status || ''}
|
||||
error={workflowRunningData?.result?.error}
|
||||
elapsed_time={workflowRunningData?.result?.elapsed_time}
|
||||
|
||||
Reference in New Issue
Block a user