From 73c25e5a2023610b5e54a1c3a1cb5b91756e84ff Mon Sep 17 00:00:00 2001 From: oudecheng <13802883547@139.com> Date: Sat, 15 Aug 2026 15:35:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20Task=20=E5=8D=A1=E7=89=87=E5=B7=AE?= =?UTF-8?q?=E5=BC=82=E6=98=BE=E7=A4=BA=E5=AD=90=E4=BB=A3=E7=90=86=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=90=8D=20+=20=E5=AD=90=E4=BB=A3=E7=90=86=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E7=8A=B6=E6=80=81=E8=BD=AC=E5=8F=91=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Task/tool 卡片头部在子代理模型与主代理不同(model 或 provider 任一不同)时显示模型徽章 - useChat 放行带 subagent_task_id 的 execution_completed 消息,更新卡片 running→completed 状态 --- web/src/components/Chat/MessageBubble.tsx | 24 +++++++++++++++++++++++ web/src/components/Chat/MessageList.tsx | 4 ++++ web/src/hooks/useChat.ts | 4 +++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/web/src/components/Chat/MessageBubble.tsx b/web/src/components/Chat/MessageBubble.tsx index 3d289da..3706a4d 100644 --- a/web/src/components/Chat/MessageBubble.tsx +++ b/web/src/components/Chat/MessageBubble.tsx @@ -89,6 +89,8 @@ interface MessageBubbleProps { message: ChatMessage; onNavigateToSubAgent?: (taskId: string, description: string, subagentType?: string) => void; showThinking?: boolean; + /** 主代理当前生效模型(Task 卡片差异显示:子代理模型不同才展示模型徽章) */ + effectiveModel?: { provider: string; model: string } | null; } function getAttachmentIcon(mediaType: string) { @@ -352,6 +354,7 @@ export const MessageBubble = memo(function MessageBubble({ message, onNavigateToSubAgent, showThinking = true, + effectiveModel, }: MessageBubbleProps) { const isUser = message.role === 'user'; const isTool = message.role === 'tool'; @@ -484,6 +487,19 @@ export const MessageBubble = memo(function MessageBubble({ // 安全获取 task 状态配色,未知状态回退到默认(避免 undefined.borderColor 崩溃) const taskStyle = taskResult ? (taskStatusConfig[taskResult.status] ?? taskStatusConfig.failed) : null; + // 子代理模型徽章:结果携带模型信息,且(无主代理参照 或 model/provider 任一不同)时展示。 + // provider 不同即使 model 同名也显示——不同 provider 的同名模型在路由/计费上已不同。 + const modelDiffers = + !effectiveModel || + effectiveModel.model !== taskResult?.model || + effectiveModel.provider !== taskResult?.provider; + const subagentModelLabel = + taskResult?.model && modelDiffers + ? effectiveModel && effectiveModel.provider === taskResult.provider + ? taskResult.model + : `${taskResult.provider ?? '?'}/${taskResult.model}` + : null; + return (
+ {subagentModelLabel && ( + + {subagentModelLabel} + + )} (null); const isAtBottomRef = useRef(true); @@ -274,6 +277,7 @@ export function MessageList({ message={message} onNavigateToSubAgent={onNavigateToSubAgent} showThinking={showThinking} + effectiveModel={effectiveModel} />
diff --git a/web/src/hooks/useChat.ts b/web/src/hooks/useChat.ts index b12db08..0dcae29 100644 --- a/web/src/hooks/useChat.ts +++ b/web/src/hooks/useChat.ts @@ -182,7 +182,9 @@ export function useChat(): UseChatReturn { // Tier 3: 主视图路由 // 3a: 带 subagent_task_id 的消息在主视图直接丢弃(已在 Tier 2 未命中) - if (getSubagentTaskId(message)) return; + // 例外:execution_completed 携带 subagent_status,需转发到 handleMainViewMessage + // 更新主视图 task 卡片占位状态(running → completed 等),否则卡片永远显示运行中 + if (getSubagentTaskId(message) && message.type !== 'execution_completed') return; // 3b: 非 chat 消息的 case 分发 switch (message.type) {