mirror of
https://github.com/langgenius/dify.git
synced 2026-09-08 02:43:49 +08:00
feat(web): template download
This commit is contained in:
parent
670ab16ea1
commit
ba951b01de
@ -11,15 +11,6 @@ const mockUseEvaluationConfig = vi.hoisted(() => vi.fn())
|
|||||||
const mockUseEvaluationNodeInfoMutation = vi.hoisted(() => vi.fn())
|
const mockUseEvaluationNodeInfoMutation = vi.hoisted(() => vi.fn())
|
||||||
const mockUseSaveEvaluationConfigMutation = vi.hoisted(() => vi.fn())
|
const mockUseSaveEvaluationConfigMutation = vi.hoisted(() => vi.fn())
|
||||||
const mockUseStartEvaluationRunMutation = vi.hoisted(() => vi.fn())
|
const mockUseStartEvaluationRunMutation = vi.hoisted(() => vi.fn())
|
||||||
const mockUsePublishedPipelineInfo = vi.hoisted(() => vi.fn())
|
|
||||||
|
|
||||||
vi.mock('@/context/dataset-detail', () => ({
|
|
||||||
useDatasetDetailContextWithSelector: (selector: (state: { dataset?: { pipeline_id?: string } }) => unknown) => selector({
|
|
||||||
dataset: {
|
|
||||||
pipeline_id: 'pipeline-1',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () => ({
|
vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () => ({
|
||||||
useModelList: () => ({
|
useModelList: () => ({
|
||||||
@ -64,10 +55,6 @@ vi.mock('@/service/use-evaluation', () => ({
|
|||||||
useStartEvaluationRunMutation: (...args: unknown[]) => mockUseStartEvaluationRunMutation(...args),
|
useStartEvaluationRunMutation: (...args: unknown[]) => mockUseStartEvaluationRunMutation(...args),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
vi.mock('@/service/use-pipeline', () => ({
|
|
||||||
usePublishedPipelineInfo: (...args: unknown[]) => mockUsePublishedPipelineInfo(...args),
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock('@/service/use-workflow', () => ({
|
vi.mock('@/service/use-workflow', () => ({
|
||||||
useAppWorkflow: () => ({
|
useAppWorkflow: () => ({
|
||||||
data: {
|
data: {
|
||||||
@ -165,24 +152,6 @@ describe('Evaluation', () => {
|
|||||||
isPending: false,
|
isPending: false,
|
||||||
mutate: vi.fn(),
|
mutate: vi.fn(),
|
||||||
})
|
})
|
||||||
mockUsePublishedPipelineInfo.mockReturnValue({
|
|
||||||
data: {
|
|
||||||
rag_pipeline_variables: [{
|
|
||||||
belong_to_node_id: 'shared',
|
|
||||||
type: 'text-input',
|
|
||||||
label: 'Question',
|
|
||||||
variable: 'question',
|
|
||||||
required: true,
|
|
||||||
}, {
|
|
||||||
belong_to_node_id: 'shared',
|
|
||||||
type: 'number',
|
|
||||||
label: 'Top K',
|
|
||||||
variable: 'top_k',
|
|
||||||
required: false,
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
isLoading: false,
|
|
||||||
})
|
|
||||||
mockUpload.mockResolvedValue({
|
mockUpload.mockResolvedValue({
|
||||||
id: 'uploaded-file-id',
|
id: 'uploaded-file-id',
|
||||||
name: 'evaluation.csv',
|
name: 'evaluation.csv',
|
||||||
@ -469,15 +438,15 @@ describe('Evaluation', () => {
|
|||||||
fireEvent.click(screen.getByRole('button', { name: /Context Precision/i }))
|
fireEvent.click(screen.getByRole('button', { name: /Context Precision/i }))
|
||||||
fireEvent.click(screen.getByRole('button', { name: 'evaluation.pipeline.uploadAndRun' }))
|
fireEvent.click(screen.getByRole('button', { name: 'evaluation.pipeline.uploadAndRun' }))
|
||||||
|
|
||||||
expect(screen.getAllByText('question').length).toBeGreaterThan(0)
|
expect(screen.getAllByText('query').length).toBeGreaterThan(0)
|
||||||
expect(screen.getAllByText('top_k').length).toBeGreaterThan(0)
|
expect(screen.getAllByText('Expect Results').length).toBeGreaterThan(0)
|
||||||
|
|
||||||
const fileInput = document.querySelector<HTMLInputElement>('input[type="file"][accept=".csv,.xlsx"]')
|
const fileInput = document.querySelector<HTMLInputElement>('input[type="file"][accept=".csv,.xlsx"]')
|
||||||
expect(fileInput).toBeInTheDocument()
|
expect(fileInput).toBeInTheDocument()
|
||||||
|
|
||||||
fireEvent.change(fileInput!, {
|
fireEvent.change(fileInput!, {
|
||||||
target: {
|
target: {
|
||||||
files: [new File(['case_id,input,expected'], 'pipeline-evaluation.csv', { type: 'text/csv' })],
|
files: [new File(['query,Expect Results'], 'pipeline-evaluation.csv', { type: 'text/csv' })],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import type { StartNodeType } from '@/app/components/workflow/nodes/start/types'
|
import type { StartNodeType } from '@/app/components/workflow/nodes/start/types'
|
||||||
import type { InputVar, Node } from '@/app/components/workflow/types'
|
import type { InputVar, Node } from '@/app/components/workflow/types'
|
||||||
import type { RAGPipelineVariables } from '@/models/pipeline'
|
|
||||||
import { inputVarTypeToVarType } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
import { inputVarTypeToVarType } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
||||||
import { inputVarTypeToVarType as pipelineInputVarTypeToVarType } from '@/app/components/workflow/nodes/data-source/utils'
|
|
||||||
import { BlockEnum, InputVarType } from '@/app/components/workflow/types'
|
import { BlockEnum, InputVarType } from '@/app/components/workflow/types'
|
||||||
|
|
||||||
export type InputField = {
|
export type InputField = {
|
||||||
@ -29,18 +27,6 @@ export const getStartNodeInputFields = (nodes?: Node[]): InputField[] => {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRagPipelineInputFields = (variables?: RAGPipelineVariables): InputField[] => {
|
|
||||||
if (!Array.isArray(variables))
|
|
||||||
return []
|
|
||||||
|
|
||||||
return variables
|
|
||||||
.filter(variable => typeof variable.variable === 'string' && !!variable.variable)
|
|
||||||
.map(variable => ({
|
|
||||||
name: variable.variable,
|
|
||||||
type: pipelineInputVarTypeToVarType(variable.type),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
const escapeCsvCell = (value: string) => {
|
const escapeCsvCell = (value: string) => {
|
||||||
if (!/[",\n\r]/.test(value))
|
if (!/[",\n\r]/.test(value))
|
||||||
return value
|
return value
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import type { EvaluationResourceType } from '../../../types'
|
import type { EvaluationResourceType } from '../../../types'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
|
|
||||||
import { usePublishedPipelineInfo } from '@/service/use-pipeline'
|
|
||||||
import { useSnippetPublishedWorkflow } from '@/service/use-snippet-workflows'
|
import { useSnippetPublishedWorkflow } from '@/service/use-snippet-workflows'
|
||||||
import { useAppWorkflow } from '@/service/use-workflow'
|
import { useAppWorkflow } from '@/service/use-workflow'
|
||||||
import { getGraphNodes, getRagPipelineInputFields, getStartNodeInputFields } from './input-fields-utils'
|
import { getGraphNodes, getStartNodeInputFields } from './input-fields-utils'
|
||||||
|
|
||||||
export const usePublishedInputFields = (
|
export const usePublishedInputFields = (
|
||||||
resourceType: EvaluationResourceType,
|
resourceType: EvaluationResourceType,
|
||||||
@ -12,8 +10,6 @@ export const usePublishedInputFields = (
|
|||||||
) => {
|
) => {
|
||||||
const { data: currentAppWorkflow, isLoading: isAppWorkflowLoading } = useAppWorkflow(resourceType === 'apps' ? resourceId : '')
|
const { data: currentAppWorkflow, isLoading: isAppWorkflowLoading } = useAppWorkflow(resourceType === 'apps' ? resourceId : '')
|
||||||
const { data: currentSnippetWorkflow, isLoading: isSnippetWorkflowLoading } = useSnippetPublishedWorkflow(resourceType === 'snippets' ? resourceId : '')
|
const { data: currentSnippetWorkflow, isLoading: isSnippetWorkflowLoading } = useSnippetPublishedWorkflow(resourceType === 'snippets' ? resourceId : '')
|
||||||
const pipelineId = useDatasetDetailContextWithSelector(state => state.dataset?.pipeline_id)
|
|
||||||
const { data: currentPipelineWorkflow, isLoading: isPipelineWorkflowLoading } = usePublishedPipelineInfo(resourceType === 'datasets' ? (pipelineId ?? '') : '')
|
|
||||||
|
|
||||||
const inputFields = useMemo(() => {
|
const inputFields = useMemo(() => {
|
||||||
if (resourceType === 'apps')
|
if (resourceType === 'apps')
|
||||||
@ -22,16 +18,12 @@ export const usePublishedInputFields = (
|
|||||||
if (resourceType === 'snippets')
|
if (resourceType === 'snippets')
|
||||||
return getStartNodeInputFields(getGraphNodes(currentSnippetWorkflow?.graph))
|
return getStartNodeInputFields(getGraphNodes(currentSnippetWorkflow?.graph))
|
||||||
|
|
||||||
if (resourceType === 'datasets')
|
|
||||||
return getRagPipelineInputFields(currentPipelineWorkflow?.rag_pipeline_variables)
|
|
||||||
|
|
||||||
return []
|
return []
|
||||||
}, [currentAppWorkflow?.graph.nodes, currentPipelineWorkflow?.rag_pipeline_variables, currentSnippetWorkflow?.graph, resourceType])
|
}, [currentAppWorkflow?.graph.nodes, currentSnippetWorkflow?.graph, resourceType])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
inputFields,
|
inputFields,
|
||||||
isInputFieldsLoading: (resourceType === 'apps' && isAppWorkflowLoading)
|
isInputFieldsLoading: (resourceType === 'apps' && isAppWorkflowLoading)
|
||||||
|| (resourceType === 'snippets' && isSnippetWorkflowLoading)
|
|| (resourceType === 'snippets' && isSnippetWorkflowLoading),
|
||||||
|| (resourceType === 'datasets' && isPipelineWorkflowLoading),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,13 +10,17 @@ import { getEvaluationMockConfig } from '../../mock'
|
|||||||
import { isEvaluationRunnable, useEvaluationResource, useEvaluationStore } from '../../store'
|
import { isEvaluationRunnable, useEvaluationResource, useEvaluationStore } from '../../store'
|
||||||
import UploadRunPopover from '../batch-test-panel/input-fields/upload-run-popover'
|
import UploadRunPopover from '../batch-test-panel/input-fields/upload-run-popover'
|
||||||
import { useInputFieldsActions } from '../batch-test-panel/input-fields/use-input-fields-actions'
|
import { useInputFieldsActions } from '../batch-test-panel/input-fields/use-input-fields-actions'
|
||||||
import { usePublishedInputFields } from '../batch-test-panel/input-fields/use-published-input-fields'
|
|
||||||
import JudgeModelSelector from '../judge-model-selector'
|
import JudgeModelSelector from '../judge-model-selector'
|
||||||
import PipelineHistoryTable from '../pipeline/pipeline-history-table'
|
import PipelineHistoryTable from '../pipeline/pipeline-history-table'
|
||||||
import PipelineMetricItem from '../pipeline/pipeline-metric-item'
|
import PipelineMetricItem from '../pipeline/pipeline-metric-item'
|
||||||
import PipelineResultsPanel from '../pipeline/pipeline-results-panel'
|
import PipelineResultsPanel from '../pipeline/pipeline-results-panel'
|
||||||
import SectionHeader, { InlineSectionHeader } from '../section-header'
|
import SectionHeader, { InlineSectionHeader } from '../section-header'
|
||||||
|
|
||||||
|
const PIPELINE_INPUT_FIELDS = [
|
||||||
|
{ name: 'query', type: 'string' },
|
||||||
|
{ name: 'Expect Results', type: 'string' },
|
||||||
|
]
|
||||||
|
|
||||||
const PipelineEvaluation = ({
|
const PipelineEvaluation = ({
|
||||||
resourceType,
|
resourceType,
|
||||||
resourceId,
|
resourceId,
|
||||||
@ -44,12 +48,11 @@ const PipelineEvaluation = ({
|
|||||||
}, [availableMetricIds, builtinMetricMap, config.builtinMetrics])
|
}, [availableMetricIds, builtinMetricMap, config.builtinMetrics])
|
||||||
const isConfigReady = !!resource.judgeModelId && builtinMetricMap.size > 0
|
const isConfigReady = !!resource.judgeModelId && builtinMetricMap.size > 0
|
||||||
const isRunnable = isEvaluationRunnable(resource)
|
const isRunnable = isEvaluationRunnable(resource)
|
||||||
const { inputFields, isInputFieldsLoading } = usePublishedInputFields(resourceType, resourceId)
|
|
||||||
const actions = useInputFieldsActions({
|
const actions = useInputFieldsActions({
|
||||||
resourceType,
|
resourceType,
|
||||||
resourceId,
|
resourceId,
|
||||||
inputFields,
|
inputFields: PIPELINE_INPUT_FIELDS,
|
||||||
isInputFieldsLoading,
|
isInputFieldsLoading: false,
|
||||||
isPanelReady: isConfigReady,
|
isPanelReady: isConfigReady,
|
||||||
isRunnable,
|
isRunnable,
|
||||||
templateFileName: config.templateFileName,
|
templateFileName: config.templateFileName,
|
||||||
@ -142,7 +145,7 @@ const PipelineEvaluation = ({
|
|||||||
onOpenChange={actions.setIsUploadPopoverOpen}
|
onOpenChange={actions.setIsUploadPopoverOpen}
|
||||||
triggerDisabled={actions.uploadButtonDisabled}
|
triggerDisabled={actions.uploadButtonDisabled}
|
||||||
triggerLabel={t('pipeline.uploadAndRun')}
|
triggerLabel={t('pipeline.uploadAndRun')}
|
||||||
inputFields={inputFields}
|
inputFields={PIPELINE_INPUT_FIELDS}
|
||||||
currentFileName={actions.currentFileName}
|
currentFileName={actions.currentFileName}
|
||||||
currentFileExtension={actions.currentFileExtension}
|
currentFileExtension={actions.currentFileExtension}
|
||||||
currentFileSize={actions.currentFileSize}
|
currentFileSize={actions.currentFileSize}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user