From 8f5b6c299d40a94ef652f7867cb3e3d7afd26765 Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Tue, 24 Mar 2026 13:30:42 +0200 Subject: [PATCH] Conform to ActivitySnapshot update using the same message_id --- app/frontend/components/Chat.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/frontend/components/Chat.tsx b/app/frontend/components/Chat.tsx index 33919dc2..b5f8de4b 100644 --- a/app/frontend/components/Chat.tsx +++ b/app/frontend/components/Chat.tsx @@ -468,11 +468,20 @@ function ChatContentInner({ } }, [JSON.stringify(agent.messages), ragState, sessionId]); + // Deduplicate messages by id, keeping the last occurrence. + // haiku.skills 0.10.0+ sends activity snapshots with the same id + // and replace=true — CopilotKit doesn't deduplicate these, so we + // must do it to avoid React duplicate key warnings. // biome-ignore lint/correctness/useExhaustiveDependencies: stable identity via agent ref - const messages = useMemo( - () => [...agent.messages], - [JSON.stringify(agent.messages)], - ); + const messages = useMemo(() => { + const seen = new Map(); + const msgs = agent.messages; + for (let i = 0; i < msgs.length; i++) { + const id = msgs[i].id; + if (id) seen.set(id, i); + } + return msgs.filter((msg, i) => !msg.id || seen.get(msg.id) === i); + }, [JSON.stringify(agent.messages)]); const onSubmitMessage = useCallback( async (text: string) => {