"use client"; import { FilesIcon, XIcon } from "lucide-react"; import { useParams, useRouter } from "next/navigation"; import { useCallback, useEffect, useMemo, useState } from "react"; import { ConversationEmptyState } from "@/components/ai-elements/conversation"; import { Button } from "@/components/ui/button"; import { ResizableHandle, ResizablePanel, ResizablePanelGroup, } from "@/components/ui/resizable"; import { useSidebar } from "@/components/ui/sidebar"; import { ArtifactFileDetail, ArtifactFileList, useArtifacts, } from "@/components/workspace/artifacts"; import { InputBox } from "@/components/workspace/input-box"; import { MessageList } from "@/components/workspace/messages"; import { ThreadContext } from "@/components/workspace/messages/context"; import { ThreadTitle } from "@/components/workspace/thread-title"; import { TodoList } from "@/components/workspace/todo-list"; import { Tooltip } from "@/components/workspace/tooltip"; import { Welcome } from "@/components/workspace/welcome"; import { useI18n } from "@/core/i18n/hooks"; import { useLocalSettings } from "@/core/settings"; import { type AgentThread } from "@/core/threads"; import { useSubmitThread, useThreadStream } from "@/core/threads/hooks"; import { pathOfThread, titleOfThread } from "@/core/threads/utils"; import { uuid } from "@/core/utils/uuid"; import { env } from "@/env"; import { cn } from "@/lib/utils"; export default function ChatPage() { const { t } = useI18n(); const router = useRouter(); const [settings, setSettings] = useLocalSettings(); const { setOpen: setSidebarOpen } = useSidebar(); const { artifacts, open: artifactsOpen, setOpen: setArtifactsOpen, setArtifacts, select: selectArtifact, selectedArtifact, } = useArtifacts(); const { thread_id: threadIdFromPath } = useParams<{ thread_id: string }>(); const isNewThread = useMemo( () => threadIdFromPath === "new", [threadIdFromPath], ); const [threadId, setThreadId] = useState(null); useEffect(() => { if (threadIdFromPath !== "new") { setThreadId(threadIdFromPath); } else { setThreadId(uuid()); } }, [threadIdFromPath]); const thread = useThreadStream({ isNewThread, threadId, }); const title = useMemo(() => { let result = isNewThread ? "" : titleOfThread(thread as unknown as AgentThread); if (result === "Untitled") { result = ""; } return result; }, [thread, isNewThread]); const [autoSelectFirstArtifact, setAutoSelectFirstArtifact] = useState(true); useEffect(() => { setArtifacts(thread.values.artifacts); if ( env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true" && autoSelectFirstArtifact ) { if (thread?.values?.artifacts?.length > 0) { setAutoSelectFirstArtifact(false); selectArtifact(thread.values.artifacts[0]!); } } }, [ autoSelectFirstArtifact, selectArtifact, setArtifacts, thread.values.artifacts, ]); const artifactPanelOpen = useMemo(() => { if (env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true") { return artifactsOpen && artifacts?.length > 0; } return artifactsOpen; }, [artifactsOpen, artifacts]); const [todoListCollapsed, setTodoListCollapsed] = useState( env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY !== "true", ); const handleSubmit = useSubmitThread({ isNewThread, threadId, thread, threadContext: { ...settings.context, thinking_enabled: settings.context.mode !== "flash", is_plan_mode: settings.context.mode === "pro", }, afterSubmit() { router.push(pathOfThread(threadId!)); }, }); const handleStop = useCallback(async () => { await thread.stop(); }, [thread]); if (!threadId) { return null; } return (
{title !== "Untitled" && ( )}
{artifacts?.length > 0 && !artifactsOpen && ( )}
} disabled={env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true"} onContextChange={(context) => setSettings("context", context) } onSubmit={handleSubmit} onStop={handleStop} /> {env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY === "true" && (
{t.common.notAvailableInDemoMode}
)}
{selectedArtifact ? ( ) : (
{thread.values.artifacts?.length === 0 ? ( } title="No artifact selected" description="Select an artifact to view its details" /> ) : (

Artifacts

)}
)}
); }