diff --git a/backend/server/routers/dashboard_router.py b/backend/server/routers/dashboard_router.py
index c0703a37..82db7072 100644
--- a/backend/server/routers/dashboard_router.py
+++ b/backend/server/routers/dashboard_router.py
@@ -89,6 +89,7 @@ class AgentAnalytics(BaseModel):
agent_satisfaction_rates: list[dict]
agent_tool_usage: list[dict]
top_performing_agents: list[dict]
+ agent_names: dict[str, str] = {} # agent_id -> agent_name 映射
class ConversationListItem(BaseModel):
@@ -486,7 +487,7 @@ async def get_agent_analytics(
):
"""获取智能体分析(管理员权限)"""
try:
- from yuxi.storage.postgres.models_business import Conversation, Message, MessageFeedback, ToolCall
+ from yuxi.storage.postgres.models_business import Agent, Conversation, Message, MessageFeedback, ToolCall
# 获取所有智能体
agents_result = await db.execute(
@@ -557,12 +558,19 @@ async def get_agent_analytics(
top_performing_agents.sort(key=lambda x: x["conversation_count"], reverse=True)
top_performing_agents = top_performing_agents[:5]
+ agent_slugs = [agent_id for agent_id, _ in agents if agent_id]
+ agent_names = {}
+ if agent_slugs:
+ agent_names_result = await db.execute(select(Agent.slug, Agent.name).where(Agent.slug.in_(agent_slugs)))
+ agent_names = {slug: name for slug, name in agent_names_result.all()}
+
return AgentAnalytics(
total_agents=total_agents,
agent_conversation_counts=agent_conversation_counts,
agent_satisfaction_rates=agent_satisfaction,
agent_tool_usage=agent_tool_usage,
top_performing_agents=top_performing_agents,
+ agent_names=agent_names,
)
except Exception as e:
@@ -718,6 +726,7 @@ class TimeSeriesStats(BaseModel):
average_count: float
peak_count: int
peak_date: str
+ agent_names: dict[str, str] | None = None # agent_id -> agent_name 映射(仅 type=agents)
@dashboard.get("/stats/calls/timeseries", response_model=TimeSeriesStats)
@@ -729,7 +738,7 @@ async def get_call_timeseries_stats(
):
"""获取调用分析时间序列统计(管理员权限)"""
try:
- from yuxi.storage.postgres.models_business import Conversation, Message, ToolCall
+ from yuxi.storage.postgres.models_business import Agent, Conversation, Message, ToolCall
# 计算时间范围(使用北京时间 UTC+8)
now = utc_now()
@@ -887,6 +896,13 @@ async def get_call_timeseries_stats(
categories = sorted(list(categories))
+ agent_names = None
+ if type == "agents" and categories:
+ agent_slugs = [c for c in categories if c]
+ if agent_slugs:
+ result = await db.execute(select(Agent.slug, Agent.name).where(Agent.slug.in_(agent_slugs)))
+ agent_names = {slug: name for slug, name in result.all()}
+
# 重新组织数据:按时间点分组每个类别的数据
time_data = {}
@@ -961,6 +977,7 @@ async def get_call_timeseries_stats(
average_count=average_count,
peak_count=peak_data["total"],
peak_date=peak_data["date"],
+ agent_names=agent_names,
)
except HTTPException:
diff --git a/web/src/components/dashboard/AgentStatsComponent.vue b/web/src/components/dashboard/AgentStatsComponent.vue
index 58e6f49f..26188988 100644
--- a/web/src/components/dashboard/AgentStatsComponent.vue
+++ b/web/src/components/dashboard/AgentStatsComponent.vue
@@ -63,7 +63,7 @@
- {{ record.agent_id }}
+ {{ resolveAgentName(record.agent_id) }}
{
return props.agentStats?.top_performing_agents || []
})
+const agentNames = computed(() => props.agentStats?.agent_names || {})
+
+const resolveAgentName = (agentId) => agentNames.value[agentId] || agentId
+
// 初始化对话数和工具调用数合并图表
const initConversationToolChart = () => {
if (
@@ -235,7 +239,7 @@ const initConversationToolChart = () => {
},
xAxis: {
type: 'category',
- data: topAgentIds,
+ data: topAgentIds.map(resolveAgentName),
axisLine: {
lineStyle: {
color: getCSSVariable('--gray-200')
diff --git a/web/src/components/dashboard/CallStatsComponent.vue b/web/src/components/dashboard/CallStatsComponent.vue
index fa9d8d0c..2955a344 100644
--- a/web/src/components/dashboard/CallStatsComponent.vue
+++ b/web/src/components/dashboard/CallStatsComponent.vue
@@ -169,8 +169,15 @@ const renderCallStatsChart = () => {
}
})
+ const agentNames = callStatsData.value.agent_names || {}
+
+ const resolveCategoryLabel = (cat) => {
+ if (cat === 'None') return '未知模型'
+ return agentNames[cat] || cat
+ }
+
const series = categories.map((category, index) => ({
- name: category === 'None' ? '未知模型' : category,
+ name: resolveCategoryLabel(category),
type: 'bar',
stack: 'total',
emphasis: { focus: 'series' },
@@ -234,7 +241,7 @@ const renderCallStatsChart = () => {
}
},
legend: {
- data: categories.map((cat) => (cat === 'None' ? '未知模型' : cat)),
+ data: categories.map(resolveCategoryLabel),
bottom: 5 /* 调整图例位置,从0改为5 */,
textStyle: { color: getCSSVariable('--gray-500'), fontSize: 12 },
itemWidth: 14,