feat(ui): display agent name in message header

This commit is contained in:
2025-12-16 10:43:02 +08:00
parent a6c1e792fa
commit e698ec2a64
6 changed files with 72 additions and 6 deletions
+28
View File
@@ -36,6 +36,8 @@ interface ChatState {
agentMode: AgentModeType;
/** 是否自动授权文件写入/编辑 (会话级别) */
autoApprove: boolean;
/** 当前正在执行的 Agent 名称 */
currentAgent: string;
}
export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdated, onConfigError }: UseChatOptions) {
@@ -47,6 +49,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
permissionRequest: null,
agentMode: 'build',
autoApprove: false,
currentAgent: 'build',
});
const wsRef = useRef<WebSocket | null>(null);
@@ -138,6 +141,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
timestamp: new Date().toISOString(),
parts: [] as MessagePart[],
content: '',
metadata: { agentName: prev.currentAgent },
};
// 复制 parts 数组以进行修改
@@ -180,6 +184,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
timestamp: new Date().toISOString(),
parts: [] as MessagePart[],
content: '',
metadata: { agentName: prev.currentAgent },
};
// 添加工具调用 part
@@ -192,11 +197,19 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
arguments: payload.arguments,
};
// 如果是 task 工具,切换到子 agent
const newAgent =
payload.toolName === 'task' && payload.arguments?.subagent_type
? (payload.arguments.subagent_type as string)
: prev.currentAgent;
return {
...prev,
currentAgent: newAgent,
streamingMessage: {
...streaming,
parts: [...streaming.parts, toolPart],
metadata: { ...streaming.metadata, agentName: newAgent },
},
};
});
@@ -222,11 +235,20 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
return part;
});
// 查找完成的工具是否为 task,如果是则恢复主 agent
const completedTool = prev.streamingMessage.parts.find(
(part) => part.type === 'tool' && part.id === payload.id
);
const isTaskTool = completedTool?.type === 'tool' && completedTool.toolName === 'task';
const newAgent = isTaskTool ? prev.agentMode : prev.currentAgent;
return {
...prev,
currentAgent: newAgent,
streamingMessage: {
...prev.streamingMessage,
parts,
metadata: { ...prev.streamingMessage.metadata, agentName: newAgent },
},
};
});
@@ -238,6 +260,8 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
// 使用流式消息或创建新消息
const streaming = prev.streamingMessage;
const content = message.payload?.content || streaming?.content || '';
// 从服务器 payload 获取 agentName,或使用当前 agentMode
const agentName = message.payload?.agentName || prev.agentMode;
const newMessage: Message = streaming
? {
@@ -245,6 +269,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
id: message.payload?.id || streaming.id,
timestamp: message.payload?.timestamp || streaming.timestamp,
content,
metadata: { ...streaming.metadata, agentName },
}
: {
id: message.payload?.id || `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
@@ -252,6 +277,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
timestamp: message.payload?.timestamp || new Date().toISOString(),
parts: [{ type: 'text', id: `text-${Date.now()}`, text: content }],
content,
metadata: { agentName },
};
return {
@@ -259,6 +285,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
messages: [...prev.messages, newMessage],
streamingMessage: null,
isLoading: false,
currentAgent: prev.agentMode, // 恢复为主 agent
};
});
break;
@@ -448,6 +475,7 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
permissionRequest: null,
agentMode: 'build',
autoApprove: false,
currentAgent: 'build',
});
reconnectAttemptsRef.current = 0;