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