diff --git a/frontend/src/app/workspace/chats/[thread_id]/layout.tsx b/frontend/src/app/workspace/chats/[thread_id]/layout.tsx index 8771037..1270b8e 100644 --- a/frontend/src/app/workspace/chats/[thread_id]/layout.tsx +++ b/frontend/src/app/workspace/chats/[thread_id]/layout.tsx @@ -1,5 +1,8 @@ "use client"; +import { useParams } from "next/navigation"; +import { useEffect, useRef, useState } from "react"; + import { PromptInputProvider } from "@/components/ai-elements/prompt-input"; import { ArtifactsProvider } from "@/components/workspace/artifacts"; import { SubtasksProvider } from "@/core/tasks/context"; @@ -9,8 +12,24 @@ export default function ChatLayout({ }: { children: React.ReactNode; }) { + const { thread_id } = useParams<{ thread_id: string }>(); + const prevThreadId = useRef(thread_id); + + // Increment only when navigating TO "new" from a non-"new" route. + // This forces a full remount of the subtree for a fresh new-chat state, + // without remounting when the URL transitions from "new" → actual-id + // (which would interrupt streaming). + const [generation, setGeneration] = useState(0); + + useEffect(() => { + if (thread_id === "new" && prevThreadId.current !== "new") { + setGeneration((g) => g + 1); + } + prevThreadId.current = thread_id; + }, [thread_id]); + return ( - + {children} diff --git a/frontend/src/app/workspace/chats/[thread_id]/page.tsx b/frontend/src/app/workspace/chats/[thread_id]/page.tsx index e8fad2f..0bc0225 100644 --- a/frontend/src/app/workspace/chats/[thread_id]/page.tsx +++ b/frontend/src/app/workspace/chats/[thread_id]/page.tsx @@ -1,5 +1,6 @@ "use client"; +import { useRouter } from "next/navigation"; import { useCallback } from "react"; import { type PromptInputMessage } from "@/components/ai-elements/prompt-input"; @@ -25,6 +26,7 @@ import { cn } from "@/lib/utils"; export default function ChatPage() { const { t } = useI18n(); + const router = useRouter(); const [settings, setSettings] = useLocalSettings(); const { threadId, isNewThread, setIsNewThread, isMock } = useThreadChat(); @@ -38,7 +40,11 @@ export default function ChatPage() { isMock, onStart: () => { setIsNewThread(false); - history.replaceState(null, "", `/workspace/chats/${threadId}`); + // Use router.replace so Next.js Router's internal state is updated. + // This ensures subsequent "New Chat" clicks are treated as a real + // cross-route navigation (actual-id → "new") rather than a no-op + // same-path navigation, which was causing stale content to persist. + router.replace(`/workspace/chats/${threadId}`); }, onFinish: (state) => { if (document.hidden || !document.hasFocus()) {