diff --git a/docs/public/bb.png b/docs/public/bb.png index 6f073577..71350bc9 100644 Binary files a/docs/public/bb.png and b/docs/public/bb.png differ diff --git a/server/routers/chat_router.py b/server/routers/chat_router.py index 75d77724..bf7a759d 100644 --- a/server/routers/chat_router.py +++ b/server/routers/chat_router.py @@ -224,15 +224,18 @@ async def save_partial_message(conv_mgr, thread_id, full_msg=None, error_message error_type: 错误类型标识 """ try: + extra_metadata = { + "error_type": error_type, + "is_error": True, + "error_message": error_message or f"发生错误: {error_type}" + } if full_msg: # 保存部分生成的AI消息 msg_dict = full_msg.model_dump() if hasattr(full_msg, "model_dump") else {} content = full_msg.content if hasattr(full_msg, "content") else str(full_msg) extra_metadata = msg_dict | {"error_type": error_type} else: - # 保存纯错误消息 - content = error_message or f"发生错误: {error_type}" - extra_metadata = {"error_type": error_type, "is_error": True} + content = "" saved_msg = conv_mgr.add_message_by_thread_id( thread_id=thread_id, @@ -517,14 +520,24 @@ async def chat_agent( # Input guard if conf.enable_content_guard and await content_guard.check(query): - yield make_chunk(status="error", message="输入内容包含敏感词", meta=meta) + yield make_chunk( + status="error", + error_type="content_guard_blocked", + error_message="输入内容包含敏感词", + meta=meta + ) return try: agent = agent_manager.get_agent(agent_id) except Exception as e: logger.error(f"Error getting agent {agent_id}: {e}, {traceback.format_exc()}") - yield make_chunk(message=f"Error getting agent {agent_id}: {e}", status="error") + yield make_chunk( + status="error", + error_type="agent_error", + error_message=f"智能体 {agent_id} 获取失败: {str(e)}", + meta=meta + ) return messages = [human_message] @@ -671,7 +684,12 @@ async def chat_agent( finally: new_db.close() - yield make_chunk(message=error_msg, status="error") + yield make_chunk( + status="error", + error_type=error_type, + error_message=error_msg, + meta=meta + ) return StreamingResponse(stream_messages(), media_type="application/json") @@ -880,6 +898,8 @@ async def get_agent_history( "content": msg.content, "created_at": msg.created_at.isoformat() if msg.created_at else None, "error_type": msg.extra_metadata.get("error_type") if msg.extra_metadata else None, + "error_message": msg.extra_metadata.get("error_message") if msg.extra_metadata else None, + "extra_metadata": msg.extra_metadata, # 保留完整的metadata以备前端需要 "message_type": msg.message_type, # 添加消息类型字段 "image_content": msg.image_content, # 添加图片内容字段 } diff --git a/server/routers/dashboard_router.py b/server/routers/dashboard_router.py index 0dec596e..e931bcbc 100644 --- a/server/routers/dashboard_router.py +++ b/server/routers/dashboard_router.py @@ -560,27 +560,24 @@ async def get_agent_analytics( agent_tool_usage.append({"agent_id": agent_id, "tool_usage_count": tool_usage_count}) - # 表现最佳的智能体(综合评分) + # 表现最佳的智能体(按对话数排序) top_performing_agents = [] for i, (agent_id, conv_count) in enumerate(agents): - # 综合评分 = 对话数权重 + 满意度权重 + # 获取满意度数据 satisfaction_data = next( (s for s in agent_satisfaction if s["agent_id"] == agent_id), {"satisfaction_rate": 0} ) - score = conv_count * 0.3 + satisfaction_data["satisfaction_rate"] * 0.7 - top_performing_agents.append( { "agent_id": agent_id, - "score": round(score, 2), "conversation_count": conv_count, "satisfaction_rate": satisfaction_data["satisfaction_rate"], } ) - # 按评分排序,取前5名 - top_performing_agents.sort(key=lambda x: x["score"], reverse=True) + # 按对话数排序,取前5名 + top_performing_agents.sort(key=lambda x: x["conversation_count"], reverse=True) top_performing_agents = top_performing_agents[:5] return AgentAnalytics( diff --git a/web/src/assets/css/base.css b/web/src/assets/css/base.css index 714c836f..ba9e4bfa 100644 --- a/web/src/assets/css/base.css +++ b/web/src/assets/css/base.css @@ -40,76 +40,64 @@ --gray-10: #fbfcfc; --gray-0: #ffffff; + /* Standard Color System - 标准5档色阶系统 */ + --color-primary-50: #e1f6fb; /* 主色调-最浅 */ + --color-primary-100: #a3d8e8; /* 主色调-浅 */ + --color-primary-500: #3996ae; /* 主色调-标准 */ + --color-primary-700: #046a82; /* 主色调-深 */ + --color-primary-900: #023944; /* 主色调-最深 */ + + /* 保留原有的 main 变量 */ --main-color: #016179; - /* 鲜艳一点的 */ --main-bright: #0188a6; - --secondry-color: #4e616d; - --error-color: #ba1a1a; - --color-primary: #1c7796; - --color-primary-bg: #d6eef1; - --color-success: #45b30e; - --color-success-light: #f6ffed; - --color-error: #c73234; - --color-error-light: #fff2f0; - --color-info: #0058d4; - --color-info-light: #e6f7ff; - --color-warning: #faad14; - --color-warning-light: #fffbe6; - /* Chart Colors - 图表颜色系统 */ - --chart-primary: var(--main-500); /* 主色调 - 用于主要数据 */ - --chart-primary-light: var(--main-400); /* 主色调浅色 - 用于渐变 */ - --chart-primary-dark: var(--main-600); /* 主色调深色 - 用于强调 */ + --color-secondary-50: #f5f7f7; /* 次要色-最浅 */ + --color-secondary-100: #eff2f2; /* 次要色-浅 */ + --color-secondary-500: #4e616d; /* 次要色-标准 */ + --color-secondary-700: #3a4a56; /* 次要色-深 */ + --color-secondary-900: #2c3843; /* 次要色-最深 */ - --chart-success: #52c41a; /* 成功色 - 绿色 */ - --chart-success-light: #95de64; /* 成功色浅色 */ - --chart-success-dark: #389e0d; /* 成功色深色 */ + --color-success-50: #f6ffed; /* 成功色-最浅 */ + --color-success-100: #b7eb8f; /* 成功色-浅 */ + --color-success-500: #52c41a; /* 成功色-标准 */ + --color-success-700: #389e0d; /* 成功色-深 */ + --color-success-900: #135200; /* 成功色-最深 */ - --chart-warning: #faad14; /* 警告色 - 橙色 */ - --chart-warning-light: #ffd666; /* 警告色浅色 */ - --chart-warning-dark: #d48806; /* 警告色深色 */ + --color-error-50: #fff2f0; /* 错误色-最浅 */ + --color-error-100: #ffccc7; /* 错误色-浅 */ + --color-error-500: #ff4d4f; /* 错误色-标准 */ + --color-error-700: #cf1322; /* 错误色-深 */ + --color-error-900: #820014; /* 错误色-最深 */ - --chart-error: #f5222d; /* 错误色 - 红色 */ - --chart-error-light: #ff7875; /* 错误色浅色 */ - --chart-error-dark: #cf1322; /* 错误色深色 */ + --color-warning-50: #fffbe6; /* 警告色-最浅 */ + --color-warning-100: #ffe58f; /* 警告色-浅 */ + --color-warning-500: #faad14; /* 警告色-标准 */ + --color-warning-700: #d48806; /* 警告色-深 */ + --color-warning-900: #ad6800; /* 警告色-最深 */ - --chart-info: #1890ff; /* 信息色 - 蓝色 */ - --chart-info-light: #69c0ff; /* 信息色浅色 */ - --chart-info-dark: #096dd9; /* 信息色深色 */ + --color-info-50: #e6f7ff; /* 信息色-最浅 */ + --color-info-100: #bae7ff; /* 信息色-浅 */ + --color-info-500: #1890ff; /* 信息色-标准 */ + --color-info-700: #096dd9; /* 信息色-深 */ + --color-info-900: #0050b3; /* 信息色-最深 */ - --chart-secondary: #722ed1; /* 次要色 - 紫色 */ - --chart-secondary-light: #b37feb; /* 次要色浅色 */ - --chart-secondary-dark: #531dab; /* 次要色深色 */ - - --chart-accent: #13c2c2; /* 强调色 - 青色 */ - --chart-accent-light: #5cdbd3; /* 强调色浅色 */ - --chart-accent-dark: #08979c; /* 强调色深色 */ + --color-accent-50: #e6fffb; /* 强调色-最浅 */ + --color-accent-100: #87e8de; /* 强调色-浅 */ + --color-accent-500: #13c2c2; /* 强调色-标准 */ + --color-accent-700: #08979c; /* 强调色-深 */ + --color-accent-900: #006d75; /* 强调色-最深 */ /* Chart Palette - 图表调色板 */ - --chart-palette-1: var(--chart-primary); - --chart-palette-2: #11cbe3; /* 浅一点的青蓝 */ - --chart-palette-3: #00b8a9; /* 明亮青绿(邻近色) */ - --chart-palette-4: #f2c94c; /* 柔和金黄(对比色) */ - --chart-palette-5: #eb5757; /* 温暖红橙(强调) */ - --chart-palette-6: #2f80ed; /* 明亮蓝色(辅助) */ - --chart-palette-7: #9b51e0; /* 紫色(分类区分) */ - --chart-palette-8: #56ccf2; /* 天蓝色(柔和点缀) */ - --chart-palette-9: #6fcf97; /* 淡绿色(平衡) */ - --chart-palette-10: #333333; /* 深灰(中性补充) */ - - /* Stats Card Colors - 统计卡片颜色系统 */ - --stats-primary-bg: #eff6ff; /* 主色调背景 */ - --stats-primary-color: #2563eb; /* 主色调文字 */ - --stats-success-bg: #f0fdf4; /* 成功色背景 */ - --stats-success-color: #16a34a; /* 成功色文字 */ - --stats-info-bg: #f0f9ff; /* 信息色背景 */ - --stats-info-color: #0284c7; /* 信息色文字 */ - --stats-warning-bg: #fffbeb; /* 警告色背景 */ - --stats-warning-color: #d97706; /* 警告色文字 */ - --stats-secondary-bg: #faf5ff; /* 次要色背景 */ - --stats-secondary-color: #9333ea; /* 次要色文字 */ - --stats-error-bg: #fef2f2; /* 错误色背景 */ - --stats-error-color: #dc2626; /* 错误色文字 */ + --chart-palette-1: var(--main-500); + --chart-palette-2: #5AD8A6; + --chart-palette-3: #F6BD16; + --chart-palette-4: #F27C7C; + --chart-palette-5: #9581CC; + --chart-palette-6: #6DC8EC; + --chart-palette-7: #FF9D4D; + --chart-palette-8: #92D050; + --chart-palette-9: #E885BA; + --chart-palette-10: #8C8C8C; --bg-sider: var(--main-5); --color-text: var(--c-black); @@ -122,11 +110,6 @@ --shadow-4: rgba(0, 0, 0, 0.16); --shadow-5: rgba(0, 0, 0, 0.20); - /* Extended Chart Variables - 扩展图表变量 */ - --chart-primary-lighter: var(--chart-primary-light); - --chart-info-lighter: var(--chart-info-light); - --chart-primary-shadow: rgba(28, 119, 150, 0.3); - --chart-info-shadow: rgba(24, 144, 255, 0.3); --min-width: 400px; diff --git a/web/src/assets/css/base.dark.css b/web/src/assets/css/base.dark.css index c7a99414..ca81f7ca 100644 --- a/web/src/assets/css/base.dark.css +++ b/web/src/assets/css/base.dark.css @@ -38,63 +38,64 @@ --gray-10: #080808; --gray-0: #030303; + /* Standard Color System - 深色模式5档色阶系统 */ + --color-primary-50: #023944; /* 主色调-最深 */ + --color-primary-100: #035065; /* 主色调-深 */ + --color-primary-500: #4a9fb8; /* 主色调-标准 */ + --color-primary-700: #5faec2; /* 主色调-浅 */ + --color-primary-900: #82c3d6; /* 主色调-最浅 */ + + /* 保留原有的 main 变量 */ --main-color: #4a9fb8; --main-bright: #5faec2; - --secondry-color: #8fa5b0; - --error-color: #ff6b6b; - --color-primary: #4a9fb8; - --color-primary-bg: #1a3a42; - --color-success: #52c41a; - --color-success-light: #162312; - --color-error: #ff4d4f; - --color-error-light: #2a1215; - --color-info: #3d8fff; - --color-info-light: #111b26; - --color-warning: #faad14; - --color-warning-light: #2b2111; - /* Chart Colors - 深色模式图表颜色 */ - --chart-primary: var(--main-500); - --chart-primary-light: var(--main-600); - --chart-primary-dark: var(--main-400); + --color-secondary-50: #151616; /* 次要色-最深 */ + --color-secondary-100: #1e1f1f; /* 次要色-深 */ + --color-secondary-500: #8fa5b0; /* 次要色-标准 */ + --color-secondary-700: #9fb5c0; /* 次要色-浅 */ + --color-secondary-900: #b8c8d0; /* 次要色-最浅 */ - --chart-success: #52c41a; - --chart-success-light: #73d13d; - --chart-success-dark: #389e0d; + --color-success-50: #162312; /* 成功色-最深 */ + --color-success-100: #273921; /* 成功色-深 */ + --color-success-500: #52c41a; /* 成功色-标准 */ + --color-success-700: #73d13d; /* 成功色-浅 */ + --color-success-900: #95de64; /* 成功色-最浅 */ - --chart-warning: #faad14; - --chart-warning-light: #ffc53d; - --chart-warning-dark: #d48806; + --color-error-50: #2a1215; /* 错误色-最深 */ + --color-error-100: #58181c; /* 错误色-深 */ + --color-error-500: #ff4d4f; /* 错误色-标准 */ + --color-error-700: #ff7875; /* 错误色-浅 */ + --color-error-900: #ffa39e; /* 错误色-最浅 */ - --chart-error: #ff4d4f; - --chart-error-light: #ff7875; - --chart-error-dark: #cf1322; + --color-warning-50: #2b2111; /* 警告色-最深 */ + --color-warning-100: #614700; /* 警告色-深 */ + --color-warning-500: #faad14; /* 警告色-标准 */ + --color-warning-700: #ffc53d; /* 警告色-浅 */ + --color-warning-900: #ffd666; /* 警告色-最浅 */ - --chart-info: #1890ff; - --chart-info-light: #40a9ff; - --chart-info-dark: #096dd9; + --color-info-50: #111b26; /* 信息色-最深 */ + --color-info-100: #111d2c; /* 信息色-深 */ + --color-info-500: #3d8fff; /* 信息色-标准 */ + --color-info-700: #40a9ff; /* 信息色-浅 */ + --color-info-900: #69c0ff; /* 信息色-最浅 */ - --chart-secondary: #722ed1; - --chart-secondary-light: #9254de; - --chart-secondary-dark: #531dab; + --color-accent-50: #0f2e2e; /* 强调色-最深 */ + --color-accent-100: #164e63; /* 强调色-深 */ + --color-accent-500: #13c2c2; /* 强调色-标准 */ + --color-accent-700: #36cfc9; /* 强调色-浅 */ + --color-accent-900: #5cdbd3; /* 强调色-最浅 */ - --chart-accent: #13c2c2; - --chart-accent-light: #36cfc9; - --chart-accent-dark: #08979c; + --chart-palette-1: var(--main-300); + --chart-palette-2: #3EA896; + --chart-palette-3: #D6AD37; + --chart-palette-4: #CF6666; + --chart-palette-5: #8672B4; + --chart-palette-6: #529AB8; + --chart-palette-7: #D48242; + --chart-palette-8: #82B354; + --chart-palette-9: #C46E9E; + --chart-palette-10: #7A7A7A; - /* Stats Card Colors - 深色模式统计卡片 */ - --stats-primary-bg: #1e3a8a; - --stats-primary-color: #93c5fd; - --stats-success-bg: #14532d; - --stats-success-color: #86efac; - --stats-info-bg: #0c4a6e; - --stats-info-color: #7dd3fc; - --stats-warning-bg: #78350f; - --stats-warning-color: #fcd34d; - --stats-secondary-bg: #581c87; - --stats-secondary-color: #d8b4fe; - --stats-error-bg: #7f1d1d; - --stats-error-color: #fca5a5; --bg-sider: #141414; --color-text: #ffffff; @@ -113,11 +114,6 @@ --shadow-4: rgba(0, 0, 0, 0.5); --shadow-5: rgba(0, 0, 0, 0.6); - /* Extended Chart Variables - 扩展图表变量 */ - --chart-primary-lighter: var(--chart-primary-light); - --chart-info-lighter: var(--chart-info-light); - --chart-primary-shadow: rgba(74, 159, 184, 0.4); - --chart-info-shadow: rgba(24, 144, 255, 0.4); --color-trans-light: rgba(0, 0, 0, 0.85); --color-trans-dark: rgba(255, 255, 255, 0.85); @@ -129,14 +125,14 @@ --markmap-a-hover-color: var(--main-600); --markmap-code-bg: var(--gray-50); --markmap-code-color: var(--gray-700); - --markmap-highlight-bg: var(--color-warning-light); + --markmap-highlight-bg: var(--color-warning-50); --markmap-table-border: 1px solid currentColor; --markmap-font: 300 16px / 20px sans-serif; --markmap-circle-open-bg: var(--main-0); --markmap-text-color: var(--gray-700); - --markmap-highlight-node-bg: var(--color-error-light); + --markmap-highlight-node-bg: var(--color-error-50); } :root.dark .md-editor { --md-bk-color: var(--gray-0); -} \ No newline at end of file +} diff --git a/web/src/assets/css/dashboard.css b/web/src/assets/css/dashboard.css index 06bbc000..7db998b4 100644 --- a/web/src/assets/css/dashboard.css +++ b/web/src/assets/css/dashboard.css @@ -7,8 +7,8 @@ type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ - { offset: 0, color: 'var(--chart-primary)' }, - { offset: 1, color: 'var(--chart-primary-light)' } + { offset: 0, color: 'var(--chart-primary-500)' }, + { offset: 1, color: 'var(--chart-primary-100)' } ] }; @@ -16,8 +16,8 @@ type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ - { offset: 0, color: 'var(--chart-success)' }, - { offset: 1, color: 'var(--chart-success-light)' } + { offset: 0, color: 'var(--color-success-500)' }, + { offset: 1, color: 'var(--color-success-100)' } ] }; @@ -25,8 +25,8 @@ type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ - { offset: 0, color: 'var(--chart-warning)' }, - { offset: 1, color: 'var(--chart-warning-light)' } + { offset: 0, color: 'var(--color-warning-500)' }, + { offset: 1, color: 'var(--color-warning-100)' } ] }; @@ -34,8 +34,8 @@ type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ - { offset: 0, color: 'var(--chart-error)' }, - { offset: 1, color: 'var(--chart-error-light)' } + { offset: 0, color: 'var(--color-error-500)' }, + { offset: 1, color: 'var(--color-error-100)' } ] }; @@ -43,8 +43,8 @@ type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ - { offset: 0, color: 'var(--chart-info)' }, - { offset: 1, color: 'var(--chart-info-light)' } + { offset: 0, color: 'var(--color-info-500)' }, + { offset: 1, color: 'var(--color-info-100)' } ] }; @@ -52,8 +52,8 @@ type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ - { offset: 0, color: 'var(--chart-secondary)' }, - { offset: 1, color: 'var(--chart-secondary-light)' } + { offset: 0, color: 'var(--color-accent-500)' }, + { offset: 1, color: 'var(--color-accent-100)' } ] }; @@ -61,8 +61,8 @@ type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ - { offset: 0, color: 'var(--chart-accent)' }, - { offset: 1, color: 'var(--chart-accent-light)' } + { offset: 0, color: 'var(--color-accent-500)' }, + { offset: 1, color: 'var(--color-accent-100)' } ] }; } @@ -245,6 +245,11 @@ color: var(--gray-1000); } +/* 强制设置所有统计卡片数字为粗体 */ +.dashboard-card .ant-statistic-content-value { + font-weight: 700 !important; +} + .dashboard-card .ant-table { background-color: var(--gray-0); border-radius: 8px; diff --git a/web/src/assets/css/sigma.css b/web/src/assets/css/sigma.css index 703cc4f9..a05e1e75 100644 --- a/web/src/assets/css/sigma.css +++ b/web/src/assets/css/sigma.css @@ -21,35 +21,35 @@ /* 高亮样式 */ .node-highlighted { - stroke: var(--color-error) !important; - stroke-width: 3px !important; + stroke: var(--color-error-500); + stroke-width: 3px; } .edge-highlighted { - stroke: var(--color-error) !important; - stroke-width: 3px !important; + stroke: var(--color-error-500); + stroke-width: 3px; } /* 选中样式 */ .node-selected { - stroke: var(--color-info) !important; - stroke-width: 4px !important; + stroke: var(--color-info-500); + stroke-width: 4px; } .edge-selected { - stroke: var(--color-info) !important; - stroke-width: 4px !important; + stroke: var(--color-info-500); + stroke-width: 4px; } /* 悬停样式 */ .node-focused { - stroke: var(--color-success) !important; - stroke-width: 2px !important; + stroke: var(--color-success-500); + stroke-width: 2px; } .edge-focused { - stroke: var(--color-success) !important; - stroke-width: 2px !important; + stroke: var(--color-success-500); + stroke-width: 2px; } /* 加载动画 */ diff --git a/web/src/components/AgentConfigSidebar.vue b/web/src/components/AgentConfigSidebar.vue index 23f1b070..6689acd0 100644 --- a/web/src/components/AgentConfigSidebar.vue +++ b/web/src/components/AgentConfigSidebar.vue @@ -734,9 +734,9 @@ watch(() => props.isOpen, (newVal) => { .system-prompt-display { min-height: 60px; background: var(--gray-50); - border: 1px solid var(--gray-200); + border: 1px dashed var(--gray-200); border-radius: 6px; - padding: 8px 12px; + padding: 6px; cursor: pointer; position: relative; transition: all 0.2s ease; @@ -774,10 +774,10 @@ watch(() => props.isOpen, (newVal) => { top: 8px; right: 12px; font-size: 12px; - color: var(--gray-400); + color: var(--gray-800); opacity: 0; transition: opacity 0.2s ease; - background: rgba(255, 255, 255, 0.9); + background: var(--gray-0); padding: 2px 6px; border-radius: 4px; } @@ -890,8 +890,8 @@ watch(() => props.isOpen, (newVal) => { .option-card { border: 1px solid var(--gray-300); - border-radius: 6px; - padding: 10px 12px; + border-radius: 8px; + padding: 8px 12px; cursor: pointer; transition: all 0.2s ease; background: var(--gray-0); @@ -946,30 +946,6 @@ watch(() => props.isOpen, (newVal) => { // 工具选择弹窗样式 .tools-modal { - :deep(.ant-modal-content) { - border-radius: 8px; - overflow: hidden; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - border: 1px solid var(--gray-200); - } - - :deep(.ant-modal-header) { - background: var(--gray-0); - border-bottom: 1px solid var(--gray-200); - padding: 16px 20px; - - .ant-modal-title { - font-size: 16px; - font-weight: 600; - color: var(--gray-900); - } - } - - :deep(.ant-modal-body) { - padding: 20px; - background: var(--gray-0); - } - .tools-modal-content { .tools-search { margin-bottom: 16px; @@ -1010,7 +986,6 @@ watch(() => props.isOpen, (newVal) => { overflow-y: auto; border-radius: 8px; margin-bottom: 16px; - background: var(--gray-0); // 在小屏幕下调整为单列布局 @media (max-width: 480px) { @@ -1085,19 +1060,19 @@ watch(() => props.isOpen, (newVal) => { } &.selected { - background: var(--main-30); - // border-color: var(--main-color); + background: var(--main-50); + border-color: var(--main-200); .tool-content { .tool-name { - color: var(--main-color); + color: var(--main-800); } .tool-indicator { - color: var(--main-color); + color: var(--main-800); } } .tool-description { - color: var(--gray-700); + color: var(--gray-900); } } diff --git a/web/src/components/AgentMessageComponent.vue b/web/src/components/AgentMessageComponent.vue index a5df374c..56a013be 100644 --- a/web/src/components/AgentMessageComponent.vue +++ b/web/src/components/AgentMessageComponent.vue @@ -34,10 +34,12 @@
-
- 回答生成已中断 +
+ {{ getErrorMessage }} + 回答生成已中断 生成过程中出现异常 检测到敏感内容,已中断输出 + {{ message.error_type || '未知错误' }}
@@ -153,6 +155,38 @@ const emit = defineEmits(['retry', 'retryStoppedMessage', 'openRefs']); const reasoningActiveKey = ref(['hide']); const expandedToolCalls = ref(new Set()); // 展开的工具调用集合 +// 错误消息处理 +const displayError = computed(() => { + // 简化错误判断:只检查明确的错误类型标识 + return !!(props.message.error_type || props.message.extra_metadata?.error_type); +}); + +const getErrorMessage = computed(() => { + // 优先使用直接的 error_message 字段 + if (props.message.error_message) { + return props.message.error_message; + } + + // 其次从 extra_metadata 中获取具体的错误信息 + if (props.message.extra_metadata?.error_message) { + return props.message.extra_metadata.error_message; + } + + // 对于已知的错误类型,返回默认提示 + switch (props.message.error_type) { + case 'interrupted': + return '回答生成已中断'; + case 'content_guard_blocked': + return '检测到敏感内容,已中断输出'; + case 'unexpect': + return '生成过程中出现异常'; + case 'agent_error': + return '智能体获取失败'; + default: + return null; + } +}); + // 引入智能体 store const agentStore = useAgentStore(); const infoStore = useInfoStore(); @@ -297,12 +331,12 @@ const toggleToolCall = (toolCallId) => { } .err-msg { - color: var(--color-error); + color: var(--color-error-500); border: 1px solid currentColor; padding: 0.5rem 1rem; border-radius: 8px; text-align: left; - background: var(--color-error-light); + background: var(--color-error-50); margin-bottom: 10px; cursor: pointer; } @@ -374,9 +408,9 @@ const toggleToolCall = (toolCallId) => { display: flex; align-items: center; gap: 8px; - background-color: var(--color-error-light); + background-color: var(--color-error-50); // border: 1px solid #f87171; - color: var(--color-error); + color: var(--color-error-500); span { line-height: 1.5; } @@ -457,15 +491,15 @@ const toggleToolCall = (toolCallId) => { } .tool-loader.tool-success { - color: var(--color-success); + color: var(--color-success-500); } .tool-loader.tool-error { - color: var(--color-error); + color: var(--color-error-500); } .tool-loader.tool-loading { - color: var(--color-info); + color: var(--color-info-500); } } @@ -528,7 +562,7 @@ const toggleToolCall = (toolCallId) => { } .retry-link { - color: var(--color-info); + color: var(--color-info-500); cursor: pointer; margin-left: 4px; @@ -539,10 +573,10 @@ const toggleToolCall = (toolCallId) => { .ant-btn-icon-only { &:has(.anticon-stop) { - background-color: var(--color-error) !important; + background-color: var(--color-error-500) !important; &:hover { - background-color: var(--chart-error-light) !important; + background-color: var(--color-error-100) !important; } } } @@ -760,4 +794,4 @@ const toggleToolCall = (toolCallId) => { font-size: 14px; } } - \ No newline at end of file + diff --git a/web/src/components/AgentPopover.vue b/web/src/components/AgentPopover.vue index f64547b4..25b10f32 100644 --- a/web/src/components/AgentPopover.vue +++ b/web/src/components/AgentPopover.vue @@ -341,13 +341,13 @@ const emitRefresh = () => { transition: all 0.15s ease; &.completed { - background: var(--stats-success-bg); - color: var(--stats-success-color); + background: var(--color-success-50); + color: var(--color-success-700); } &.in_progress { - background: var(--stats-warning-bg); - color: var(--stats-warning-color); + background: var(--color-warning-50); + color: var(--color-warning-700); } &.pending { diff --git a/web/src/components/AttachmentStatusIndicator.vue b/web/src/components/AttachmentStatusIndicator.vue index 50da1357..13107821 100644 --- a/web/src/components/AttachmentStatusIndicator.vue +++ b/web/src/components/AttachmentStatusIndicator.vue @@ -286,7 +286,7 @@ const handleRemoveAttachment = (fileId) => { transition: all 0.15s ease; &:hover:not(:disabled) { - color: var(--color-error); + color: var(--color-error-500); } &:disabled { diff --git a/web/src/components/DebugComponent.vue b/web/src/components/DebugComponent.vue index 63388054..b418525c 100644 --- a/web/src/components/DebugComponent.vue +++ b/web/src/components/DebugComponent.vue @@ -549,7 +549,7 @@ const printAgentConfig = async () => { } .error { - color: var(--error-color); + color: var(--color-error-500); } .log-container { diff --git a/web/src/components/FileTable.vue b/web/src/components/FileTable.vue index 60b8d94f..adee3de3 100644 --- a/web/src/components/FileTable.vue +++ b/web/src/components/FileTable.vue @@ -121,10 +121,10 @@ {{ text?.toUpperCase() }}
- - - - + + + +
@@ -670,11 +670,11 @@ import ChunkParamsConfig from '@/components/ChunkParamsConfig.vue'; } .my-table .rechunk-btn:hover { - color: var(--color-warning); + color: var(--color-warning-500); } .my-table .del-btn:hover { - color: var(--error-color); + color: var(--color-error-500); } .my-table .del-btn:disabled { diff --git a/web/src/components/FileUploadModal.vue b/web/src/components/FileUploadModal.vue index 3e2a7253..02fa1079 100644 --- a/web/src/components/FileUploadModal.vue +++ b/web/src/components/FileUploadModal.vue @@ -733,6 +733,6 @@ const chunkData = async () => { .zip-support-tip { font-size: 12px; - color: var(--color-warning); + color: var(--color-warning-500); } diff --git a/web/src/components/GraphInfoPanel.vue b/web/src/components/GraphInfoPanel.vue index 29cc5d66..6d3ebd3f 100644 --- a/web/src/components/GraphInfoPanel.vue +++ b/web/src/components/GraphInfoPanel.vue @@ -97,7 +97,7 @@ defineEmits(['index-nodes', 'export-data']) font-size: 14px; &.warning { - color: var(--color-warning); + color: var(--color-warning-500); } } @@ -111,7 +111,7 @@ defineEmits(['index-nodes', 'export-data']) font-weight: 600; &.warning { - color: var(--color-warning); + color: var(--color-warning-500); } } diff --git a/web/src/components/KnowledgeGraphViewer.vue b/web/src/components/KnowledgeGraphViewer.vue index da799891..f0c00985 100644 --- a/web/src/components/KnowledgeGraphViewer.vue +++ b/web/src/components/KnowledgeGraphViewer.vue @@ -594,7 +594,7 @@ const registerEvents = () => { const graph = sigmaInstance.getGraph() if (graph.hasEdge(edge)) { // 高亮悬停的边 - graph.setEdgeAttribute(edge, 'color', getCSSVariable('--color-error')) + graph.setEdgeAttribute(edge, 'color', getCSSVariable('--color-error-500')) graph.setEdgeAttribute(edge, 'size', (graph.getEdgeAttribute(edge, 'size') || 1) * 1.5) sigmaInstance.refresh() console.log('悬停在边上:', edge) @@ -1271,11 +1271,11 @@ defineExpose({ } &.node-panel { - border-left: 4px solid var(--color-success); // 绿色边框标识节点面板 + border-left: 4px solid var(--color-success-500); // 绿色边框标识节点面板 } &.edge-panel { - border-left: 4px solid var(--color-info); // 蓝色边框标识边面板 + border-left: 4px solid var(--color-info-500); // 蓝色边框标识边面板 } } @@ -1304,11 +1304,11 @@ defineExpose({ flex-shrink: 0; &.node-indicator { - background: var(--color-success); + background: var(--color-success-500); } &.edge-indicator { - background: var(--color-info); + background: var(--color-info-500); } } diff --git a/web/src/components/MarkdownContentViewer.vue b/web/src/components/MarkdownContentViewer.vue index 1d23f61f..f6cca296 100644 --- a/web/src/components/MarkdownContentViewer.vue +++ b/web/src/components/MarkdownContentViewer.vue @@ -309,7 +309,7 @@ onUnmounted(() => { } */ /* .chunk-item.highlighted { - border-color: var(--color-success); + border-color: var(--color-success-500); background: var(--main-50); } */ diff --git a/web/src/components/ModelSelectorComponent.vue b/web/src/components/ModelSelectorComponent.vue index 4d24f6d6..91756801 100644 --- a/web/src/components/ModelSelectorComponent.vue +++ b/web/src/components/ModelSelectorComponent.vue @@ -180,9 +180,9 @@ const handleSelectModel = async (provider, name) => { \ No newline at end of file diff --git a/web/src/components/dashboard/FeedbackModalComponent.vue b/web/src/components/dashboard/FeedbackModalComponent.vue index 1441b242..970882bd 100644 --- a/web/src/components/dashboard/FeedbackModalComponent.vue +++ b/web/src/components/dashboard/FeedbackModalComponent.vue @@ -304,10 +304,10 @@ watch(() => props.agentId, () => { } .reason-content { - background: var(--color-warning-light); + background: var(--color-warning-50); padding: 10px; border-radius: 6px; - border-left: 3px solid var(--color-warning); + border-left: 3px solid var(--color-warning-500); font-size: 13px; line-height: 1.4; color: var(--gray-800); diff --git a/web/src/components/dashboard/KnowledgeStatsComponent.vue b/web/src/components/dashboard/KnowledgeStatsComponent.vue index 29ae681f..8249ca2f 100644 --- a/web/src/components/dashboard/KnowledgeStatsComponent.vue +++ b/web/src/components/dashboard/KnowledgeStatsComponent.vue @@ -7,7 +7,7 @@ @@ -15,7 +15,7 @@ @@ -23,7 +23,7 @@ @@ -103,7 +103,7 @@ - - \ No newline at end of file diff --git a/web/src/components/dashboard/UserStatsComponent.vue b/web/src/components/dashboard/UserStatsComponent.vue index 5eef0673..8486fcaa 100644 --- a/web/src/components/dashboard/UserStatsComponent.vue +++ b/web/src/components/dashboard/UserStatsComponent.vue @@ -30,8 +30,6 @@