From 8b6b3cddea932ccfae9ded554f912b5345f6a57c Mon Sep 17 00:00:00 2001 From: JzoNg Date: Fri, 10 Apr 2026 17:31:10 +0800 Subject: [PATCH] refactor(web): rag-pipeline evaluation --- .../components/layout/pipeline-evaluation.tsx | 113 ++---------------- .../pipeline/pipeline-batch-actions.tsx | 70 +++++++++++ .../pipeline/pipeline-metrics-section.tsx | 69 +++++++++++ 3 files changed, 151 insertions(+), 101 deletions(-) create mode 100644 web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx create mode 100644 web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx diff --git a/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx b/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx index 82aadebb06..73c211f899 100644 --- a/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx +++ b/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx @@ -1,26 +1,17 @@ 'use client' import type { EvaluationResourceProps } from '../../types' -import { useEffect, useMemo } from 'react' +import { useEffect } from 'react' import { useTranslation } from 'react-i18next' -import Button from '@/app/components/base/button' import { useDocLink } from '@/context/i18n' -import { useAvailableEvaluationMetrics } from '@/service/use-evaluation' -import { getEvaluationMockConfig } from '../../mock' -import { isEvaluationRunnable, useEvaluationResource, useEvaluationStore } from '../../store' +import { useEvaluationStore } from '../../store' import HistoryTab from '../batch-test-panel/history-tab' -import UploadRunPopover from '../batch-test-panel/input-fields/upload-run-popover' -import { useInputFieldsActions } from '../batch-test-panel/input-fields/use-input-fields-actions' import JudgeModelSelector from '../judge-model-selector' -import PipelineMetricItem from '../pipeline/pipeline-metric-item' +import PipelineBatchActions from '../pipeline/pipeline-batch-actions' +import PipelineMetricsSection from '../pipeline/pipeline-metrics-section' import PipelineResultsPanel from '../pipeline/pipeline-results-panel' import SectionHeader, { InlineSectionHeader } from '../section-header' -const PIPELINE_INPUT_FIELDS = [ - { name: 'query', type: 'string' }, - { name: 'Expect Results', type: 'string' }, -] - const PipelineEvaluation = ({ resourceType, resourceId, @@ -29,49 +20,11 @@ const PipelineEvaluation = ({ const { t: tCommon } = useTranslation('common') const docLink = useDocLink() const ensureResource = useEvaluationStore(state => state.ensureResource) - const addBuiltinMetric = useEvaluationStore(state => state.addBuiltinMetric) - const removeMetric = useEvaluationStore(state => state.removeMetric) - const updateMetricThreshold = useEvaluationStore(state => state.updateMetricThreshold) - const { data: availableMetricsData } = useAvailableEvaluationMetrics() - const resource = useEvaluationResource(resourceType, resourceId) - const config = getEvaluationMockConfig(resourceType) - const builtinMetricMap = useMemo(() => new Map( - resource.metrics - .filter(metric => metric.kind === 'builtin') - .map(metric => [metric.optionId, metric]), - ), [resource.metrics]) - const availableMetricIds = useMemo(() => new Set(availableMetricsData?.metrics ?? []), [availableMetricsData?.metrics]) - const availableBuiltinMetrics = useMemo(() => { - return config.builtinMetrics.filter(metric => - availableMetricIds.has(metric.id) || builtinMetricMap.has(metric.id), - ) - }, [availableMetricIds, builtinMetricMap, config.builtinMetrics]) - const isConfigReady = !!resource.judgeModelId && builtinMetricMap.size > 0 - const isRunnable = isEvaluationRunnable(resource) - const actions = useInputFieldsActions({ - resourceType, - resourceId, - inputFields: PIPELINE_INPUT_FIELDS, - isInputFieldsLoading: false, - isPanelReady: isConfigReady, - isRunnable, - templateFileName: config.templateFileName, - }) useEffect(() => { ensureResource(resourceType, resourceId) }, [ensureResource, resourceId, resourceType]) - const handleToggleMetric = (metricId: string) => { - const selectedMetric = builtinMetricMap.get(metricId) - if (selectedMetric) { - removeMetric(resourceType, resourceId, selectedMetric.id) - return - } - - addBuiltinMetric(resourceType, resourceId, metricId) - } - return (
@@ -108,57 +61,15 @@ const PipelineEvaluation = ({
-
- -
- {availableBuiltinMetrics.map((metric) => { - const selectedMetric = builtinMetricMap.get(metric.id) + - return ( - handleToggleMetric(metric.id)} - onThresholdChange={value => updateMetricThreshold(resourceType, resourceId, selectedMetric?.id ?? '', value)} - /> - ) - })} -
-
- -
- -
- -
-
+
diff --git a/web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx b/web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx new file mode 100644 index 0000000000..086de8f8da --- /dev/null +++ b/web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx @@ -0,0 +1,70 @@ +'use client' + +import type { EvaluationResourceProps } from '../../types' +import type { InputField } from '../batch-test-panel/input-fields/input-fields-utils' +import { useTranslation } from 'react-i18next' +import Button from '@/app/components/base/button' +import { getEvaluationMockConfig } from '../../mock' +import { isEvaluationRunnable, useEvaluationResource } from '../../store' +import UploadRunPopover from '../batch-test-panel/input-fields/upload-run-popover' +import { useInputFieldsActions } from '../batch-test-panel/input-fields/use-input-fields-actions' + +const PIPELINE_INPUT_FIELDS: InputField[] = [ + { name: 'query', type: 'string' }, + { name: 'Expect Results', type: 'string' }, +] + +const PipelineBatchActions = ({ + resourceType, + resourceId, +}: EvaluationResourceProps) => { + const { t } = useTranslation('evaluation') + const resource = useEvaluationResource(resourceType, resourceId) + const config = getEvaluationMockConfig(resourceType) + const isConfigReady = !!resource.judgeModelId && resource.metrics.some(metric => metric.kind === 'builtin') + const isRunnable = isEvaluationRunnable(resource) + const actions = useInputFieldsActions({ + resourceType, + resourceId, + inputFields: PIPELINE_INPUT_FIELDS, + isInputFieldsLoading: false, + isPanelReady: isConfigReady, + isRunnable, + templateFileName: config.templateFileName, + }) + + return ( +
+ +
+ +
+
+ ) +} + +export default PipelineBatchActions diff --git a/web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx b/web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx new file mode 100644 index 0000000000..f9eb852f89 --- /dev/null +++ b/web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx @@ -0,0 +1,69 @@ +'use client' + +import type { EvaluationResourceProps } from '../../types' +import { useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import { useAvailableEvaluationMetrics } from '@/service/use-evaluation' +import { getEvaluationMockConfig } from '../../mock' +import { useEvaluationResource, useEvaluationStore } from '../../store' +import { InlineSectionHeader } from '../section-header' +import PipelineMetricItem from './pipeline-metric-item' + +const PipelineMetricsSection = ({ + resourceType, + resourceId, +}: EvaluationResourceProps) => { + const { t } = useTranslation('evaluation') + const addBuiltinMetric = useEvaluationStore(state => state.addBuiltinMetric) + const removeMetric = useEvaluationStore(state => state.removeMetric) + const updateMetricThreshold = useEvaluationStore(state => state.updateMetricThreshold) + const { data: availableMetricsData } = useAvailableEvaluationMetrics() + const resource = useEvaluationResource(resourceType, resourceId) + const config = getEvaluationMockConfig(resourceType) + const builtinMetricMap = useMemo(() => new Map( + resource.metrics + .filter(metric => metric.kind === 'builtin') + .map(metric => [metric.optionId, metric]), + ), [resource.metrics]) + const availableMetricIds = useMemo(() => new Set(availableMetricsData?.metrics ?? []), [availableMetricsData?.metrics]) + const availableBuiltinMetrics = useMemo(() => { + return config.builtinMetrics.filter(metric => + availableMetricIds.has(metric.id) || builtinMetricMap.has(metric.id), + ) + }, [availableMetricIds, builtinMetricMap, config.builtinMetrics]) + + const handleToggleMetric = (metricId: string) => { + const selectedMetric = builtinMetricMap.get(metricId) + if (selectedMetric) { + removeMetric(resourceType, resourceId, selectedMetric.id) + return + } + + addBuiltinMetric(resourceType, resourceId, metricId) + } + + return ( +
+ +
+ {availableBuiltinMetrics.map((metric) => { + const selectedMetric = builtinMetricMap.get(metric.id) + + return ( + handleToggleMetric(metric.id)} + onThresholdChange={value => updateMetricThreshold(resourceType, resourceId, selectedMetric?.id ?? '', value)} + /> + ) + })} +
+
+ ) +} + +export default PipelineMetricsSection