feat(web): Task 卡片差异显示子代理模型名 + 子代理完成状态转发修复
- Task/tool 卡片头部在子代理模型与主代理不同(model 或 provider 任一不同)时显示模型徽章 - useChat 放行带 subagent_task_id 的 execution_completed 消息,更新卡片 running→completed 状态
This commit is contained in:
parent
53e2fb6dc6
commit
73c25e5a20
@ -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 (
|
||||
<div data-message-id={message.id} className="animate-slide-in">
|
||||
<div
|
||||
@ -504,6 +520,14 @@ export const MessageBubble = memo(function MessageBubble({
|
||||
? `${message.toolName || 'Tool'}${taskDescription ? ` · ${taskDescription}` : ''}`
|
||||
: message.toolName || 'Tool'}
|
||||
</span>
|
||||
{subagentModelLabel && (
|
||||
<span
|
||||
className="flex-shrink-0 rounded-full border border-[var(--border-color)] bg-[var(--bg-tertiary)] px-1.5 py-px text-[10px] leading-4 text-[var(--text-muted)] max-w-[160px] truncate"
|
||||
title={`子代理模型:${taskResult?.provider ?? '?'} / ${taskResult?.model}`}
|
||||
>
|
||||
{subagentModelLabel}
|
||||
</span>
|
||||
)}
|
||||
<span
|
||||
className={`flex-shrink-0 transition-all duration-300 ${
|
||||
taskStyle ? taskStyle.iconColor : statusConfig.iconColor
|
||||
|
||||
@ -12,6 +12,8 @@ interface MessageListProps {
|
||||
viewKey?: string;
|
||||
/** 高亮的消息 ID,点击待办项后滚动并高亮显示 */
|
||||
highlightedMessageId?: string | null;
|
||||
/** 主代理当前生效模型(透传给 MessageBubble 做 Task 卡片差异显示) */
|
||||
effectiveModel?: { provider: string; model: string } | null;
|
||||
}
|
||||
|
||||
export function MessageList({
|
||||
@ -20,6 +22,7 @@ export function MessageList({
|
||||
showThinking = true,
|
||||
viewKey,
|
||||
highlightedMessageId,
|
||||
effectiveModel,
|
||||
}: MessageListProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const isAtBottomRef = useRef(true);
|
||||
@ -274,6 +277,7 @@ export function MessageList({
|
||||
message={message}
|
||||
onNavigateToSubAgent={onNavigateToSubAgent}
|
||||
showThinking={showThinking}
|
||||
effectiveModel={effectiveModel}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user