From e842ae0608f463b5b61c474714abdd9e8822ae85 Mon Sep 17 00:00:00 2001 From: oudecheng <13802883547@139.com> Date: Wed, 17 Jun 2026 14:33:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=E5=AE=9E=E7=8E=B0todo=5Fwrite?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=90=8E=E8=87=AA=E5=8A=A8=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E5=BE=85=E5=8A=9E=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在useChat中添加sendMessage引用,支持从handleServerMessage内部发送命令 - 在App.tsx中通过useEffect将sendMessage注入useChat - 子代理todo_write完成后自动发送请求刷新对应待办列表命令 - 主视图todo_write完成后自动刷新待办列表,支持子代理和主任务区分 - 优化消息处理逻辑,避免不同子代理消息混淆 --- web/src/App.tsx | 6 ++++++ web/src/hooks/useChat.ts | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/web/src/App.tsx b/web/src/App.tsx index 285dd24..67ae375 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -75,6 +75,7 @@ function App() { handleCommand, clearMessages, handleServerMessage, + setSendMessage, selectTopic, createTopic, switchTopic, @@ -92,6 +93,11 @@ function App() { onMessage: handleServerMessage, }) + // 将 sendMessage 注入到 useChat,供 handleServerMessage 内部发送命令 + useEffect(() => { + setSendMessage(sendMessage) + }, [setSendMessage, sendMessage]) + // ---- 主题状态 ---- const [memoryPanelOpen, setMemoryPanelOpen] = useState(() => { diff --git a/web/src/hooks/useChat.ts b/web/src/hooks/useChat.ts index 28063b8..d7321d1 100644 --- a/web/src/hooks/useChat.ts +++ b/web/src/hooks/useChat.ts @@ -29,6 +29,7 @@ import type { ChannelList, StreamDelta, StreamEnd, + WsInbound, } from '../types/protocol' // 简化后的层级状态 @@ -66,6 +67,7 @@ interface UseChatReturn { handleCommand: (command: Command) => void clearMessages: () => void handleServerMessage: (message: WsOutbound) => void + setSendMessage: (fn: (msg: WsInbound) => boolean) => void // Topic 方法 selectTopic: (topicId: string) => void @@ -171,6 +173,12 @@ export function useChat(): UseChatReturn { const selectedTopicRef = useRef(null) const pendingNewTopicRef = useRef(false) + // Ref to send commands from within handleServerMessage (set by App.tsx) + const sendMessageRef = useRef<((msg: WsInbound) => boolean) | null>(null) + const setSendMessage = useCallback((fn: (msg: WsInbound) => boolean) => { + sendMessageRef.current = fn + }, []) + const isConnected = useMemo(() => connectionId !== null, [connectionId]) const selectedSession = useMemo( () => sessions.find(s => s.session_id === selectedSessionId) ?? null, @@ -377,6 +385,11 @@ export function useChat(): UseChatReturn { const msgSubagentTaskId = getSubagentTaskId(message) if (msgSubagentTaskId && msgSubagentTaskId === currentSubAgentView.taskId) { appendToSubAgentViewMessage(message) + // 子代理 todo_write 完成后自动刷新待办列表 + if (message.type === 'tool_result' && (message as ToolResult).tool_name === 'todo_write') { + const refreshCmd = requestSubAgentTodoList(currentSubAgentView.taskId) + sendMessageRef.current?.({ type: 'command', payload: JSON.stringify(refreshCmd) }) + } return } // 丢弃其他子智能体的消息,避免 fall through 到主消息处理 @@ -694,6 +707,14 @@ export function useChat(): UseChatReturn { // 忽略这些消息 break } + + // 主视图 todo_write 完成后自动刷新待办列表 + if (message.type === 'tool_result' && (message as ToolResult).tool_name === 'todo_write') { + const refreshCmd = subAgentViewRef.current?.taskId + ? requestSubAgentTodoList(subAgentViewRef.current.taskId) + : requestTodoList() + sendMessageRef.current?.({ type: 'command', payload: JSON.stringify(refreshCmd) }) + } }, []) const handleMessage = useCallback((content: string, attachments?: Attachment[]) => { @@ -938,6 +959,7 @@ export function useChat(): UseChatReturn { handleCommand, clearMessages, handleServerMessage, + setSendMessage, selectTopic, createTopic, switchTopic,