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) {