mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-09 07:42:39 +02:00
refactor: update navigation and chat initialization logic
- Changed navigation from researcher to new-chat in EditorPage. - Updated NewChatPage to support lazy thread creation on first message. - Adjusted breadcrumb to not display thread ID for new-chat sections. - Improved user experience by modifying error messages and loading states. - Enhanced styling in model-selector component for better visibility.
This commit is contained in:
parent
85ddaedd9e
commit
bf22156664
5 changed files with 53 additions and 35 deletions
|
|
@ -7,7 +7,7 @@ import {
|
|||
useExternalStoreRuntime,
|
||||
} from "@assistant-ui/react";
|
||||
import { useAtomValue, useSetAtom } from "jotai";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
|
|
@ -126,7 +126,6 @@ interface ThinkingStepData {
|
|||
|
||||
export default function NewChatPage() {
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const [isInitializing, setIsInitializing] = useState(true);
|
||||
const [threadId, setThreadId] = useState<number | null>(null);
|
||||
const [messages, setMessages] = useState<ThreadMessageLike[]>([]);
|
||||
|
|
@ -168,6 +167,7 @@ export default function NewChatPage() {
|
|||
}, [params.chat_id]);
|
||||
|
||||
// Initialize thread and load messages
|
||||
// For new chats (no urlChatId), we use lazy creation - thread is created on first message
|
||||
const initializeThread = useCallback(async () => {
|
||||
setIsInitializing(true);
|
||||
|
||||
|
|
@ -206,22 +206,20 @@ export default function NewChatPage() {
|
|||
setMessageDocumentsMap(restoredDocsMap);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Create new thread
|
||||
const newThread = await createThread(searchSpaceId, "New Chat");
|
||||
setThreadId(newThread.id);
|
||||
router.replace(`/dashboard/${searchSpaceId}/new-chat/${newThread.id}`);
|
||||
}
|
||||
// For new chats (urlChatId === 0), don't create thread yet
|
||||
// Thread will be created lazily when user sends first message
|
||||
// This improves UX (instant load) and avoids orphan threads
|
||||
} catch (error) {
|
||||
console.error("[NewChatPage] Failed to initialize thread:", error);
|
||||
// Keep threadId as null - don't use Date.now() as it creates an invalid ID
|
||||
// that will cause 404 errors on subsequent API calls
|
||||
setThreadId(null);
|
||||
toast.error("Failed to initialize chat. Please try again.");
|
||||
toast.error("Failed to load chat. Please try again.");
|
||||
} finally {
|
||||
setIsInitializing(false);
|
||||
}
|
||||
}, [urlChatId, searchSpaceId, router, setMessageDocumentsMap]);
|
||||
}, [urlChatId, setMessageDocumentsMap]);
|
||||
|
||||
// Initialize on mount
|
||||
useEffect(() => {
|
||||
|
|
@ -240,8 +238,6 @@ export default function NewChatPage() {
|
|||
// Handle new message from user
|
||||
const onNew = useCallback(
|
||||
async (message: AppendMessage) => {
|
||||
if (!threadId) return;
|
||||
|
||||
// Extract user query text from content parts
|
||||
let userQuery = "";
|
||||
for (const part of message.content) {
|
||||
|
|
@ -273,6 +269,27 @@ export default function NewChatPage() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Lazy thread creation: create thread on first message if it doesn't exist
|
||||
let currentThreadId = threadId;
|
||||
if (!currentThreadId) {
|
||||
try {
|
||||
const newThread = await createThread(searchSpaceId, "New Chat");
|
||||
currentThreadId = newThread.id;
|
||||
setThreadId(currentThreadId);
|
||||
// Update URL silently using browser API (not router.replace) to avoid
|
||||
// interrupting the ongoing fetch/streaming with React navigation
|
||||
window.history.replaceState(
|
||||
null,
|
||||
"",
|
||||
`/dashboard/${searchSpaceId}/new-chat/${currentThreadId}`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("[NewChatPage] Failed to create thread:", error);
|
||||
toast.error("Failed to start chat. Please try again.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add user message to state
|
||||
const userMsgId = `msg-user-${Date.now()}`;
|
||||
const userMessage: ThreadMessageLike = {
|
||||
|
|
@ -311,7 +328,7 @@ export default function NewChatPage() {
|
|||
},
|
||||
]
|
||||
: message.content;
|
||||
appendMessage(threadId, {
|
||||
appendMessage(currentThreadId, {
|
||||
role: "user",
|
||||
content: persistContent,
|
||||
}).catch((err) => console.error("Failed to persist user message:", err));
|
||||
|
|
@ -468,7 +485,7 @@ export default function NewChatPage() {
|
|||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
chat_id: threadId,
|
||||
chat_id: currentThreadId,
|
||||
user_query: userQuery.trim(),
|
||||
search_space_id: searchSpaceId,
|
||||
messages: messageHistory,
|
||||
|
|
@ -601,7 +618,7 @@ export default function NewChatPage() {
|
|||
// Persist assistant message (with thinking steps for restoration on refresh)
|
||||
const finalContent = buildContentForPersistence();
|
||||
if (contentParts.length > 0) {
|
||||
appendMessage(threadId, {
|
||||
appendMessage(currentThreadId, {
|
||||
role: "assistant",
|
||||
content: finalContent,
|
||||
}).catch((err) => console.error("Failed to persist assistant message:", err));
|
||||
|
|
@ -678,7 +695,7 @@ export default function NewChatPage() {
|
|||
},
|
||||
});
|
||||
|
||||
// Show loading state
|
||||
// Show loading state only when loading an existing thread
|
||||
if (isInitializing) {
|
||||
return (
|
||||
<div className="flex h-[calc(100vh-64px)] items-center justify-center">
|
||||
|
|
@ -687,11 +704,12 @@ export default function NewChatPage() {
|
|||
);
|
||||
}
|
||||
|
||||
// Show error state if thread initialization failed
|
||||
if (!threadId) {
|
||||
// Show error state only if we tried to load an existing thread but failed
|
||||
// For new chats (urlChatId === 0), threadId being null is expected (lazy creation)
|
||||
if (!threadId && urlChatId > 0) {
|
||||
return (
|
||||
<div className="flex h-[calc(100vh-64px)] flex-col items-center justify-center gap-4">
|
||||
<div className="text-destructive">Failed to initialize chat</div>
|
||||
<div className="text-destructive">Failed to load chat</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue