diff --git a/web/app/components/app/workflow-log/evaluation-cell.tsx b/web/app/components/app/workflow-log/evaluation-cell.tsx
index 539ae5b538..5ccfb2e55b 100644
--- a/web/app/components/app/workflow-log/evaluation-cell.tsx
+++ b/web/app/components/app/workflow-log/evaluation-cell.tsx
@@ -9,7 +9,8 @@ import {
} from '@langgenius/dify-ui/popover'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
-import { getNodeVisual, getToneClasses } from '@/app/components/evaluation/components/metric-selector/utils'
+import { getEvaluationNodeBlockType } from '@/app/components/evaluation/components/metric-selector/utils'
+import BlockIcon from '@/app/components/workflow/block-icon'
type EvaluationCellProps = {
evaluation: EvaluationLogItem[]
@@ -60,37 +61,34 @@ const EvaluationCell = ({
popupClassName="w-[320px] overflow-hidden rounded-xl border-[0.5px] border-components-panel-border p-0 shadow-[0px_12px_16px_-4px_rgba(9,9,11,0.08),0px_4px_6px_-2px_rgba(9,9,11,0.03)]"
>
- {evaluation.map((item, index) => {
- const nodeVisual = item.nodeInfo ? getNodeVisual(item.nodeInfo) : null
- const nodeToneClasses = nodeVisual ? getToneClasses(nodeVisual.tone) : null
-
- return (
-
(
+
+
+
{item.name}
+ {item.nodeInfo && (
+
+
+
+ {item.nodeInfo.title}
+
+
)}
- >
-
-
{item.name}
- {item.nodeInfo && nodeVisual && nodeToneClasses && (
-
-
-
-
-
- {item.nodeInfo.title}
-
-
- )}
-
-
- {formatEvaluationValue(item.value)}
-
- )
- })}
+
+ {formatEvaluationValue(item.value)}
+
+
+ ))}
diff --git a/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx b/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx
index b8a4992b65..ed1ec8f4bf 100644
--- a/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx
+++ b/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx
@@ -12,8 +12,9 @@ import {
} from '@langgenius/dify-ui/dropdown-menu'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
+import BlockIcon from '@/app/components/workflow/block-icon'
import { useEvaluationStore } from '../../store'
-import { dedupeNodeInfoList, getMetricVisual, getNodeVisual, getToneClasses } from '../metric-selector/utils'
+import { dedupeNodeInfoList, getEvaluationNodeBlockType, getMetricVisual, getToneClasses } from '../metric-selector/utils'
type BuiltinMetricCardProps = EvaluationResourceProps & {
metric: EvaluationMetric
@@ -41,7 +42,7 @@ const BuiltinMetricCard = ({
return (
-
+
-
{metric.label}
+
{metric.label}
{hasNoNodeInfo && (
-
+
{t('metrics.noNodesInWorkflow')}
)}
{shownNodes.map((nodeInfo) => {
- const nodeVisual = getNodeVisual(nodeInfo)
- const nodeToneClasses = getToneClasses(nodeVisual.tone)
const isAdded = addedMetric
? addedMetric.nodeInfoList?.length
? selectedNodeIds.has(nodeInfo.node_id)
@@ -91,21 +90,23 @@ const SelectorMetricSection = ({
data-testid={`evaluation-metric-node-${metric.id}-${nodeInfo.node_id}`}
type="button"
className={cn(
- 'flex w-full items-center gap-1 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-state-base-hover-alt',
+ 'flex w-full items-center gap-1 rounded-md px-3 py-1.5 text-left transition-colors hover:bg-state-base-hover-alt',
isAdded && 'opacity-50',
)}
onClick={() => onToggleNodeSelection(metric.id, nodeInfo)}
>
{isAdded && (
-
{t('metrics.added')}
+
{t('metrics.added')}
)}
)
@@ -120,7 +121,7 @@ const SelectorMetricSection = ({
-
+
{isShowingAllNodes ? t('metrics.showLess') : t('metrics.showMore')}
diff --git a/web/app/components/evaluation/components/metric-selector/utils.ts b/web/app/components/evaluation/components/metric-selector/utils.ts
index 3bf6ebd06e..8d9dd76436 100644
--- a/web/app/components/evaluation/components/metric-selector/utils.ts
+++ b/web/app/components/evaluation/components/metric-selector/utils.ts
@@ -1,6 +1,7 @@
import type { ConditionMetricValueType, MetricOption } from '../../types'
import type { MetricVisualTone } from './types'
import type { EvaluationDefaultMetric, NodeInfo } from '@/types/evaluation'
+import { BlockEnum } from '@/app/components/workflow/types'
import { getDefaultMetricDescription } from '../../default-metric-descriptions'
const defaultConditionMetricValueType: ConditionMetricValueType = 'number'
@@ -70,17 +71,13 @@ export const getMetricVisual = (metricId: string): { icon: string, tone: MetricV
return { icon: 'i-ri-checkbox-circle-line', tone: 'indigo' }
}
-export const getNodeVisual = (nodeInfo: NodeInfo): { icon: string, tone: MetricVisualTone } => {
- const normalizedType = nodeInfo.type.toLowerCase()
- const normalizedTitle = nodeInfo.title.toLowerCase()
+const workflowBlockTypeSet = new Set(Object.values(BlockEnum))
- if (normalizedType.includes('retriev') || normalizedTitle.includes('retriev') || normalizedTitle.includes('knowledge'))
- return { icon: 'i-ri-book-open-line', tone: 'green' }
+export const getEvaluationNodeBlockType = (nodeInfo: Pick): BlockEnum => {
+ if (workflowBlockTypeSet.has(nodeInfo.type))
+ return nodeInfo.type as BlockEnum
- if (normalizedType.includes('agent') || normalizedTitle.includes('agent'))
- return { icon: 'i-ri-user-star-line', tone: 'indigo' }
-
- return { icon: 'i-ri-ai-generate-2', tone: 'indigo' }
+ return BlockEnum.LLM
}
export const getToneClasses = (tone: MetricVisualTone) => {
diff --git a/web/i18n/en-US/evaluation.json b/web/i18n/en-US/evaluation.json
index 9802bc904c..dfdde63e26 100644
--- a/web/i18n/en-US/evaluation.json
+++ b/web/i18n/en-US/evaluation.json
@@ -110,7 +110,7 @@
"metrics.groups.operations": "Operations",
"metrics.groups.other": "Other",
"metrics.groups.quality": "Quality",
- "metrics.noNodesInWorkflow": "No LLM nodes in this workflow",
+ "metrics.noNodesInWorkflow": "No selectable nodes",
"metrics.noResults": "No metrics or nodes were found",
"metrics.nodesAll": "All nodes",
"metrics.nodesLabel": "Node Scope",
diff --git a/web/i18n/zh-Hans/evaluation.json b/web/i18n/zh-Hans/evaluation.json
index 0f499426e4..1d62824b38 100644
--- a/web/i18n/zh-Hans/evaluation.json
+++ b/web/i18n/zh-Hans/evaluation.json
@@ -104,7 +104,7 @@
"metrics.groups.operations": "运行",
"metrics.groups.other": "其他",
"metrics.groups.quality": "质量",
- "metrics.noNodesInWorkflow": "当前工作流中没有 LLM 节点",
+ "metrics.noNodesInWorkflow": "没有可选节点",
"metrics.noResults": "没有匹配的指标。",
"metrics.nodesAll": "全部节点",
"metrics.nodesLabel": "节点范围",