From 76bad41ca6f6e9de7a433f7dd0c760631721e2c2 Mon Sep 17 00:00:00 2001 From: Lluis Agusti Date: Mon, 9 Feb 2026 21:24:16 +0800 Subject: [PATCH] chore: further changes --- .../src/app/(platform)/copilot-2/page.tsx | 67 - .../(platform)/copilot-2/styleguide/page.tsx | 1509 ---------------- .../(platform)/copilot-2/useCopilotPage.ts | 137 -- .../ChatContainer/ChatContainer.tsx | 0 .../ChatMessagesContainer.tsx | 0 .../components/ChatSidebar/ChatSidebar.tsx | 0 .../CopilotChatActionsProvider.tsx | 0 .../useCopilotChatActions.ts | 0 .../components/CopilotShell/CopilotShell.tsx | 99 -- .../DesktopSidebar/DesktopSidebar.tsx | 70 - .../components/MobileDrawer/MobileDrawer.tsx | 91 - .../MobileDrawer/useMobileDrawer.ts | 24 - .../components/MobileHeader/MobileHeader.tsx | 22 - .../components/SessionsList/SessionsList.tsx | 80 - .../SessionsList/useSessionsPagination.ts | 91 - .../components/CopilotShell/helpers.ts | 106 -- .../CopilotShell/useCopilotShell.ts | 124 -- .../CopilotShell/useShellSessionList.ts | 113 -- .../components/EmptySession/EmptySession.tsx | 0 .../components/EmptySession/helpers.ts | 0 .../components/MobileDrawer/MobileDrawer.tsx | 0 .../components/MobileHeader/MobileHeader.tsx | 0 .../MorphingTextAnimation.tsx | 0 .../OrbitLoader/OrbitLoader.module.css | 0 .../components/OrbitLoader/OrbitLoader.tsx | 0 .../components/ProgressBar/ProgressBar.tsx | 0 .../PulseLoader/PulseLoader.module.css | 0 .../components/PulseLoader/PulseLoader.tsx | 0 .../ToolAccordion/AccordionContent.tsx | 0 .../ToolAccordion/ToolAccordion.tsx | 0 .../ToolAccordion/useToolAccordion.ts | 0 .../(platform)/copilot/copilot-page-store.ts | 56 - .../src/app/(platform)/copilot/helpers.ts | 45 - .../helpers/convertChatSessionToUiMessages.ts | 0 .../hooks/useAsymptoticProgress.ts | 0 .../src/app/(platform)/copilot/layout.tsx | 13 - .../src/app/(platform)/copilot/page.tsx | 196 +-- .../(platform)/copilot/styleguide/page.tsx | 1533 +++++++++++++++++ .../tools/CreateAgent/CreateAgent.tsx | 0 .../tools/CreateAgent/helpers.tsx | 0 .../tools/EditAgent/EditAgent.tsx | 0 .../tools/EditAgent/helpers.tsx | 0 .../tools/FindAgents/FindAgents.tsx | 0 .../tools/FindAgents/helpers.tsx | 0 .../tools/FindBlocks/FindBlocks.tsx | 0 .../tools/FindBlocks/helpers.tsx | 0 .../tools/RunAgent/RunAgent.tsx | 0 .../AgentDetailsCard/AgentDetailsCard.tsx | 0 .../components/AgentDetailsCard/helpers.ts | 0 .../components/ErrorCard/ErrorCard.tsx | 0 .../ExecutionStartedCard.tsx | 0 .../SetupRequirementsCard.tsx | 0 .../SetupRequirementsCard/helpers.ts | 0 .../tools/RunAgent/helpers.tsx | 0 .../tools/RunBlock/RunBlock.tsx | 0 .../BlockOutputCard/BlockOutputCard.tsx | 0 .../components/ErrorCard/ErrorCard.tsx | 0 .../SetupRequirementsCard.tsx | 0 .../SetupRequirementsCard/helpers.ts | 0 .../tools/RunBlock/helpers.tsx | 0 .../tools/SearchDocs/SearchDocs.tsx | 0 .../tools/SearchDocs/helpers.tsx | 0 .../tools/ViewAgentOutput/ViewAgentOutput.tsx | 0 .../tools/ViewAgentOutput/helpers.tsx | 0 .../{copilot-2 => copilot}/useChatSession.ts | 0 .../app/(platform)/copilot/useCopilotPage.ts | 224 +-- .../(platform)/copilot/useCopilotSessionId.ts | 10 - 67 files changed, 1707 insertions(+), 2903 deletions(-) delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot-2/page.tsx delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot-2/styleguide/page.tsx delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot-2/useCopilotPage.ts rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/ChatContainer/ChatContainer.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/ChatMessagesContainer/ChatMessagesContainer.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/ChatSidebar/ChatSidebar.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/CopilotChatActionsProvider/CopilotChatActionsProvider.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/CopilotChatActionsProvider/useCopilotChatActions.ts (100%) delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/CopilotShell.tsx delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/DesktopSidebar/DesktopSidebar.tsx delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/MobileDrawer.tsx delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/useMobileDrawer.ts delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileHeader/MobileHeader.tsx delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/SessionsList.tsx delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/useSessionsPagination.ts delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/helpers.ts delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useCopilotShell.ts delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useShellSessionList.ts rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/EmptySession/EmptySession.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/EmptySession/helpers.ts (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/MobileDrawer/MobileDrawer.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/MobileHeader/MobileHeader.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/MorphingTextAnimation/MorphingTextAnimation.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/OrbitLoader/OrbitLoader.module.css (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/OrbitLoader/OrbitLoader.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/ProgressBar/ProgressBar.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/PulseLoader/PulseLoader.module.css (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/PulseLoader/PulseLoader.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/ToolAccordion/AccordionContent.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/ToolAccordion/ToolAccordion.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/components/ToolAccordion/useToolAccordion.ts (100%) delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/copilot-page-store.ts delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/helpers.ts rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/helpers/convertChatSessionToUiMessages.ts (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/hooks/useAsymptoticProgress.ts (100%) delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/layout.tsx create mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/styleguide/page.tsx rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/CreateAgent/CreateAgent.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/CreateAgent/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/EditAgent/EditAgent.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/EditAgent/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/FindAgents/FindAgents.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/FindAgents/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/FindBlocks/FindBlocks.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/FindBlocks/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/RunAgent.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/components/AgentDetailsCard/AgentDetailsCard.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/components/AgentDetailsCard/helpers.ts (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/components/ErrorCard/ErrorCard.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/components/ExecutionStartedCard/ExecutionStartedCard.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/components/SetupRequirementsCard/SetupRequirementsCard.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/components/SetupRequirementsCard/helpers.ts (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunAgent/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunBlock/RunBlock.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunBlock/components/BlockOutputCard/BlockOutputCard.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunBlock/components/ErrorCard/ErrorCard.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunBlock/components/SetupRequirementsCard/SetupRequirementsCard.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunBlock/components/SetupRequirementsCard/helpers.ts (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/RunBlock/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/SearchDocs/SearchDocs.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/SearchDocs/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/ViewAgentOutput/ViewAgentOutput.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/tools/ViewAgentOutput/helpers.tsx (100%) rename autogpt_platform/frontend/src/app/(platform)/{copilot-2 => copilot}/useChatSession.ts (100%) delete mode 100644 autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotSessionId.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/page.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot-2/page.tsx deleted file mode 100644 index 402d139db5..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot-2/page.tsx +++ /dev/null @@ -1,67 +0,0 @@ -"use client"; - -import { SidebarProvider } from "@/components/ui/sidebar"; -import { ChatContainer } from "./components/ChatContainer/ChatContainer"; -import { ChatSidebar } from "./components/ChatSidebar/ChatSidebar"; -import { MobileDrawer } from "./components/MobileDrawer/MobileDrawer"; -import { MobileHeader } from "./components/MobileHeader/MobileHeader"; -import { useCopilotPage } from "./useCopilotPage"; - -export default function Page() { - const { - sessionId, - messages, - status, - error, - isLoadingSession, - isCreatingSession, - createSession, - onSend, - // Mobile drawer - isMobile, - isDrawerOpen, - sessions, - isLoadingSessions, - handleOpenDrawer, - handleCloseDrawer, - handleDrawerOpenChange, - handleSelectSession, - handleNewChat, - } = useCopilotPage(); - - return ( - - {!isMobile && } -
- {isMobile && } -
- -
-
- {isMobile && ( - - )} -
- ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/styleguide/page.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot-2/styleguide/page.tsx deleted file mode 100644 index 6ce0fe80c9..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot-2/styleguide/page.tsx +++ /dev/null @@ -1,1509 +0,0 @@ -"use client"; - -import { - Conversation, - ConversationContent, -} from "@/components/ai-elements/conversation"; -import { - Message, - MessageContent, - MessageResponse, -} from "@/components/ai-elements/message"; -import { CopilotChatActionsProvider } from "../components/CopilotChatActionsProvider/CopilotChatActionsProvider"; -import { FindBlocksTool } from "../tools/FindBlocks/FindBlocks"; -import { FindAgentsTool } from "../tools/FindAgents/FindAgents"; -import { SearchDocsTool } from "../tools/SearchDocs/SearchDocs"; -import { RunBlockTool } from "../tools/RunBlock/RunBlock"; -import { RunAgentTool } from "../tools/RunAgent/RunAgent"; -import { CreateAgentTool } from "../tools/CreateAgent/CreateAgent"; -import { EditAgentTool } from "../tools/EditAgent/EditAgent"; -import { ViewAgentOutputTool } from "../tools/ViewAgentOutput/ViewAgentOutput"; -import { ResponseType } from "@/app/api/__generated__/models/responseType"; - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -function slugify(text: string) { - return text - .toLowerCase() - .replace(/[^a-z0-9]+/g, "-") - .replace(/(^-|-$)/g, ""); -} - -const SECTIONS = [ - "Messages", - "Tool: Find Blocks", - "Tool: Find Agents (Marketplace)", - "Tool: Find Agents (Library)", - "Tool: Search Docs", - "Tool: Get Doc Page", - "Tool: Run Block", - "Tool: Run Agent", - "Tool: Schedule Agent", - "Tool: Create Agent", - "Tool: Edit Agent", - "Tool: View Agent Output", - "Full Conversation Example", -] as const; - -function Section({ - title, - children, -}: { - title: string; - children: React.ReactNode; -}) { - return ( -
-

- {title} -

-
{children}
-
- ); -} - -function SubSection({ - label, - children, -}: { - label: string; - children: React.ReactNode; -}) { - return ( -
-

- {label} -

- {children} -
- ); -} - -// --------------------------------------------------------------------------- -// Mock data factories -// --------------------------------------------------------------------------- - -let _id = 0; -function uid() { - return `sg-${++_id}`; -} - -// --------------------------------------------------------------------------- -// Page -// --------------------------------------------------------------------------- - -export default function StyleguidePage() { - return ( - alert(`onSend: ${msg}`)}> -
- {/* Sidebar */} - - - {/* Content */} -
-
-

- Copilot Styleguide -

-

- Static showcase of all chat message types, tool states & - variants. -

- - {/* ============================================================= */} - {/* MESSAGE TYPES */} - {/* ============================================================= */} - -
- - - - - Find me an agent that can summarize YouTube videos - - - - - - - - - - I found a few agents that can help with YouTube video - summarization. Let me search for the best options for you. - - - - - - - - - - {`Here's what I found:\n\n1. **YouTube Summarizer** — Extracts key points from any YouTube video\n2. **Video Digest** — Creates bullet-point summaries with timestamps\n\n> Both agents support videos up to 2 hours long.\n\n\`\`\`python\n# Example usage\nresult = agent.run(url="https://youtube.com/watch?v=...")\nprint(result.summary)\n\`\`\``} - - - - - - - - - - Thinking... - - - - - - -
- Error: Connection timed out. Please try again. -
-
-
- - {/* ============================================================= */} - {/* FIND BLOCKS */} - {/* ============================================================= */} - -
- - - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* FIND AGENTS (Marketplace) */} - {/* ============================================================= */} - -
- - - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* FIND AGENTS (Library) */} - {/* ============================================================= */} - -
- - - - - - - -
- - {/* ============================================================= */} - {/* SEARCH DOCS */} - {/* ============================================================= */} - -
- - - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* GET DOC PAGE */} - {/* ============================================================= */} - -
- - - - - - - -
- - {/* ============================================================= */} - {/* RUN BLOCK */} - {/* ============================================================= */} - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Overall, this was our strongest quarter to date.\n\n| Metric | Q3 | Q4 | Change |\n|--------|-----|-----|--------|\n| Revenue | $2.1M | $2.6M | +23% |\n| Users | 10k | 20k | +100% |\n| NPS | 72 | 78 | +6 |", - ], - }, - }, - }} - /> - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* RUN AGENT */} - {/* ============================================================= */} - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* SCHEDULE AGENT */} - {/* ============================================================= */} - -
- - - - - - - -
- - {/* ============================================================= */} - {/* CREATE AGENT */} - {/* ============================================================= */} - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* EDIT AGENT */} - {/* ============================================================= */} - -
- - - - - - - - - - - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* VIEW AGENT OUTPUT */} - {/* ============================================================= */} - -
- - - - - - - - - - AI is not replacing doctors — it's augmenting their capabilities.\n\n### Adoption by Region\n\n| Region | Adoption Rate | Growth |\n|--------|--------------|--------|\n| North America | 78% | +15% |\n| Europe | 62% | +22% |\n| Asia Pacific | 71% | +31% |", - ], - metadata: [ - { - sources_analyzed: 142, - confidence_score: 0.94, - processing_time_ms: 3420, - model_version: "v2.3.1", - categories: [ - "healthcare", - "machine-learning", - "diagnostics", - ], - }, - ], - chart: [ - "https://picsum.photos/seed/chart-demo/500/300", - ], - }, - }, - }, - }} - /> - - - - - - - - - - - - - - - - - -
- - {/* ============================================================= */} - {/* FULL CONVERSATION EXAMPLE */} - {/* ============================================================= */} - -
- - - - - - Find me a block that can fetch weather data - - - - - - - - Let me search for weather-related blocks for you. - - - - - - I found 2 blocks related to weather. The **Get Weather** - block fetches current conditions, while **Weather - Forecast** provides a 5-day outlook. Would you like me to - run one of these? - - - - - - - - Yes, run the Get Weather block for San Francisco - - - - - - - - - - The current weather in San Francisco is **68°F** and - **Foggy** with 85% humidity and winds from the west at 12 - mph. - - - - - -
-
-
-
-
- ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/useCopilotPage.ts b/autogpt_platform/frontend/src/app/(platform)/copilot-2/useCopilotPage.ts deleted file mode 100644 index 4e2f24e1c1..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot-2/useCopilotPage.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { useGetV2ListSessions } from "@/app/api/__generated__/endpoints/chat/chat"; -import { useBreakpoint } from "@/lib/hooks/useBreakpoint"; -import { useChat } from "@ai-sdk/react"; -import { DefaultChatTransport } from "ai"; -import { useCallback, useEffect, useState } from "react"; -import { useChatSession } from "./useChatSession"; - -export function useCopilotPage() { - const [isDrawerOpen, setIsDrawerOpen] = useState(false); - const [pendingMessage, setPendingMessage] = useState(null); - - const { - sessionId, - setSessionId, - hydratedMessages, - isLoadingSession, - createSession, - isCreatingSession, - } = useChatSession(); - - const breakpoint = useBreakpoint(); - const isMobile = - breakpoint === "base" || breakpoint === "sm" || breakpoint === "md"; - - const transport = sessionId - ? new DefaultChatTransport({ - api: `/api/chat/sessions/${sessionId}/stream`, - prepareSendMessagesRequest: ({ messages }) => { - const last = messages[messages.length - 1]; - return { - body: { - message: last.parts - ?.map((p) => (p.type === "text" ? p.text : "")) - .join(""), - is_user_message: last.role === "user", - context: null, - }, - }; - }, - // Resume uses GET on the same endpoint (no message param → backend resumes) - prepareReconnectToStreamRequest: () => ({ - api: `/api/chat/sessions/${sessionId}/stream`, - }), - }) - : null; - - const { messages, sendMessage, status, error, setMessages } = useChat({ - id: sessionId ?? undefined, - transport: transport ?? undefined, - resume: !!sessionId, - }); - - useEffect(() => { - if (!hydratedMessages || hydratedMessages.length === 0) return; - setMessages((prev) => { - if (prev.length > hydratedMessages.length) return prev; - return hydratedMessages; - }); - }, [hydratedMessages, setMessages]); - - // Clear messages when session is null - useEffect(() => { - if (!sessionId) setMessages([]); - }, [sessionId, setMessages]); - - useEffect(() => { - if (!sessionId || !pendingMessage) return; - const msg = pendingMessage; - setPendingMessage(null); - sendMessage({ text: msg }); - }, [sessionId, pendingMessage, sendMessage]); - - async function onSend(message: string) { - const trimmed = message.trim(); - if (!trimmed) return; - - if (sessionId) { - sendMessage({ text: trimmed }); - return; - } - - setPendingMessage(trimmed); - await createSession(); - } - - const { data: sessionsResponse, isLoading: isLoadingSessions } = - useGetV2ListSessions({ limit: 50 }); - - const sessions = - sessionsResponse?.status === 200 ? sessionsResponse.data.sessions : []; - - const handleOpenDrawer = useCallback(() => { - setIsDrawerOpen(true); - }, []); - - const handleCloseDrawer = useCallback(() => { - setIsDrawerOpen(false); - }, []); - - const handleDrawerOpenChange = useCallback((open: boolean) => { - setIsDrawerOpen(open); - }, []); - - const handleSelectSession = useCallback( - (id: string) => { - setSessionId(id); - if (isMobile) setIsDrawerOpen(false); - }, - [setSessionId, isMobile], - ); - - const handleNewChat = useCallback(() => { - setSessionId(null); - if (isMobile) setIsDrawerOpen(false); - }, [setSessionId, isMobile]); - - return { - sessionId, - messages, - status, - error, - isLoadingSession, - isCreatingSession, - createSession, - onSend, - // Mobile drawer - isMobile, - isDrawerOpen, - sessions, - isLoadingSessions, - handleOpenDrawer, - handleCloseDrawer, - handleDrawerOpenChange, - handleSelectSession, - handleNewChat, - }; -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ChatContainer/ChatContainer.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ChatContainer/ChatContainer.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatContainer/ChatContainer.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ChatMessagesContainer/ChatMessagesContainer.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ChatMessagesContainer/ChatMessagesContainer.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatMessagesContainer/ChatMessagesContainer.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ChatSidebar/ChatSidebar.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ChatSidebar/ChatSidebar.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/ChatSidebar/ChatSidebar.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/CopilotChatActionsProvider/CopilotChatActionsProvider.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotChatActionsProvider/CopilotChatActionsProvider.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/CopilotChatActionsProvider/CopilotChatActionsProvider.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotChatActionsProvider/CopilotChatActionsProvider.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/CopilotChatActionsProvider/useCopilotChatActions.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotChatActionsProvider/useCopilotChatActions.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/CopilotChatActionsProvider/useCopilotChatActions.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotChatActionsProvider/useCopilotChatActions.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/CopilotShell.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/CopilotShell.tsx deleted file mode 100644 index 3f695da5ed..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/CopilotShell.tsx +++ /dev/null @@ -1,99 +0,0 @@ -"use client"; - -import { ChatLoader } from "@/components/contextual/Chat/components/ChatLoader/ChatLoader"; -import { Text } from "@/components/atoms/Text/Text"; -import { NAVBAR_HEIGHT_PX } from "@/lib/constants"; -import type { ReactNode } from "react"; -import { DesktopSidebar } from "./components/DesktopSidebar/DesktopSidebar"; -import { MobileDrawer } from "./components/MobileDrawer/MobileDrawer"; -import { MobileHeader } from "./components/MobileHeader/MobileHeader"; -import { useCopilotShell } from "./useCopilotShell"; - -interface Props { - children: ReactNode; -} - -export function CopilotShell({ children }: Props) { - const { - isMobile, - isDrawerOpen, - isLoading, - isCreatingSession, - isLoggedIn, - hasActiveSession, - sessions, - currentSessionId, - handleOpenDrawer, - handleCloseDrawer, - handleDrawerOpenChange, - handleNewChatClick, - handleSessionClick, - hasNextPage, - isFetchingNextPage, - fetchNextPage, - } = useCopilotShell(); - - if (!isLoggedIn) { - return ( -
- -
- ); - } - - return ( -
- {!isMobile && ( - - )} - -
- {isMobile && } -
- {isCreatingSession ? ( -
-
- - - Creating your chat... - -
-
- ) : ( - children - )} -
-
- - {isMobile && ( - - )} -
- ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/DesktopSidebar/DesktopSidebar.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/DesktopSidebar/DesktopSidebar.tsx deleted file mode 100644 index 122a09a02f..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/DesktopSidebar/DesktopSidebar.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import type { SessionSummaryResponse } from "@/app/api/__generated__/models/sessionSummaryResponse"; -import { Button } from "@/components/atoms/Button/Button"; -import { Text } from "@/components/atoms/Text/Text"; -import { scrollbarStyles } from "@/components/styles/scrollbars"; -import { cn } from "@/lib/utils"; -import { Plus } from "@phosphor-icons/react"; -import { SessionsList } from "../SessionsList/SessionsList"; - -interface Props { - sessions: SessionSummaryResponse[]; - currentSessionId: string | null; - isLoading: boolean; - hasNextPage: boolean; - isFetchingNextPage: boolean; - onSelectSession: (sessionId: string) => void; - onFetchNextPage: () => void; - onNewChat: () => void; - hasActiveSession: boolean; -} - -export function DesktopSidebar({ - sessions, - currentSessionId, - isLoading, - hasNextPage, - isFetchingNextPage, - onSelectSession, - onFetchNextPage, - onNewChat, - hasActiveSession, -}: Props) { - return ( - - ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/MobileDrawer.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/MobileDrawer.tsx deleted file mode 100644 index ea3b39f829..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/MobileDrawer.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import type { SessionSummaryResponse } from "@/app/api/__generated__/models/sessionSummaryResponse"; -import { Button } from "@/components/atoms/Button/Button"; -import { scrollbarStyles } from "@/components/styles/scrollbars"; -import { cn } from "@/lib/utils"; -import { PlusIcon, X } from "@phosphor-icons/react"; -import { Drawer } from "vaul"; -import { SessionsList } from "../SessionsList/SessionsList"; - -interface Props { - isOpen: boolean; - sessions: SessionSummaryResponse[]; - currentSessionId: string | null; - isLoading: boolean; - hasNextPage: boolean; - isFetchingNextPage: boolean; - onSelectSession: (sessionId: string) => void; - onFetchNextPage: () => void; - onNewChat: () => void; - onClose: () => void; - onOpenChange: (open: boolean) => void; - hasActiveSession: boolean; -} - -export function MobileDrawer({ - isOpen, - sessions, - currentSessionId, - isLoading, - hasNextPage, - isFetchingNextPage, - onSelectSession, - onFetchNextPage, - onNewChat, - onClose, - onOpenChange, - hasActiveSession, -}: Props) { - return ( - - - - -
-
- - Your chats - - -
-
-
- -
- {hasActiveSession && ( -
- -
- )} -
-
-
- ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/useMobileDrawer.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/useMobileDrawer.ts deleted file mode 100644 index 2ef63a4422..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileDrawer/useMobileDrawer.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { useState } from "react"; - -export function useMobileDrawer() { - const [isDrawerOpen, setIsDrawerOpen] = useState(false); - - const handleOpenDrawer = () => { - setIsDrawerOpen(true); - }; - - const handleCloseDrawer = () => { - setIsDrawerOpen(false); - }; - - const handleDrawerOpenChange = (open: boolean) => { - setIsDrawerOpen(open); - }; - - return { - isDrawerOpen, - handleOpenDrawer, - handleCloseDrawer, - handleDrawerOpenChange, - }; -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileHeader/MobileHeader.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileHeader/MobileHeader.tsx deleted file mode 100644 index e0d6161744..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/MobileHeader/MobileHeader.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Button } from "@/components/atoms/Button/Button"; -import { NAVBAR_HEIGHT_PX } from "@/lib/constants"; -import { ListIcon } from "@phosphor-icons/react"; - -interface Props { - onOpenDrawer: () => void; -} - -export function MobileHeader({ onOpenDrawer }: Props) { - return ( - - ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/SessionsList.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/SessionsList.tsx deleted file mode 100644 index ef63e1aff4..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/SessionsList.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import type { SessionSummaryResponse } from "@/app/api/__generated__/models/sessionSummaryResponse"; -import { Skeleton } from "@/components/__legacy__/ui/skeleton"; -import { Text } from "@/components/atoms/Text/Text"; -import { InfiniteList } from "@/components/molecules/InfiniteList/InfiniteList"; -import { cn } from "@/lib/utils"; -import { getSessionTitle } from "../../helpers"; - -interface Props { - sessions: SessionSummaryResponse[]; - currentSessionId: string | null; - isLoading: boolean; - hasNextPage: boolean; - isFetchingNextPage: boolean; - onSelectSession: (sessionId: string) => void; - onFetchNextPage: () => void; -} - -export function SessionsList({ - sessions, - currentSessionId, - isLoading, - hasNextPage, - isFetchingNextPage, - onSelectSession, - onFetchNextPage, -}: Props) { - if (isLoading) { - return ( -
- {Array.from({ length: 5 }).map((_, i) => ( -
- -
- ))} -
- ); - } - - if (sessions.length === 0) { - return ( -
- - You don't have previous chats - -
- ); - } - - return ( - { - const isActive = session.id === currentSessionId; - return ( - - ); - }} - /> - ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/useSessionsPagination.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/useSessionsPagination.ts deleted file mode 100644 index 61e3e6f37f..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/components/SessionsList/useSessionsPagination.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { useGetV2ListSessions } from "@/app/api/__generated__/endpoints/chat/chat"; -import type { SessionSummaryResponse } from "@/app/api/__generated__/models/sessionSummaryResponse"; -import { okData } from "@/app/api/helpers"; -import { useEffect, useState } from "react"; - -const PAGE_SIZE = 50; - -export interface UseSessionsPaginationArgs { - enabled: boolean; -} - -export function useSessionsPagination({ enabled }: UseSessionsPaginationArgs) { - const [offset, setOffset] = useState(0); - - const [accumulatedSessions, setAccumulatedSessions] = useState< - SessionSummaryResponse[] - >([]); - - const [totalCount, setTotalCount] = useState(null); - - const { data, isLoading, isFetching, isError } = useGetV2ListSessions( - { limit: PAGE_SIZE, offset }, - { - query: { - enabled: enabled && offset >= 0, - }, - }, - ); - - useEffect(() => { - const responseData = okData(data); - if (responseData) { - const newSessions = responseData.sessions; - const total = responseData.total; - setTotalCount(total); - - if (offset === 0) { - setAccumulatedSessions(newSessions); - } else { - setAccumulatedSessions((prev) => [...prev, ...newSessions]); - } - } else if (!enabled) { - setAccumulatedSessions([]); - setTotalCount(null); - } - }, [data, offset, enabled]); - - const hasNextPage = - totalCount !== null && accumulatedSessions.length < totalCount; - - const areAllSessionsLoaded = - totalCount !== null && - accumulatedSessions.length >= totalCount && - !isFetching && - !isLoading; - - useEffect(() => { - if ( - hasNextPage && - !isFetching && - !isLoading && - !isError && - totalCount !== null - ) { - setOffset((prev) => prev + PAGE_SIZE); - } - }, [hasNextPage, isFetching, isLoading, isError, totalCount]); - - const fetchNextPage = () => { - if (hasNextPage && !isFetching) { - setOffset((prev) => prev + PAGE_SIZE); - } - }; - - const reset = () => { - // Only reset the offset - keep existing sessions visible during refetch - // The effect will replace sessions when new data arrives at offset 0 - setOffset(0); - }; - - return { - sessions: accumulatedSessions, - isLoading, - isFetching, - hasNextPage, - areAllSessionsLoaded, - totalCount, - fetchNextPage, - reset, - }; -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/helpers.ts deleted file mode 100644 index ef0d414edf..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/helpers.ts +++ /dev/null @@ -1,106 +0,0 @@ -import type { SessionDetailResponse } from "@/app/api/__generated__/models/sessionDetailResponse"; -import type { SessionSummaryResponse } from "@/app/api/__generated__/models/sessionSummaryResponse"; -import { format, formatDistanceToNow, isToday } from "date-fns"; - -export function convertSessionDetailToSummary(session: SessionDetailResponse) { - return { - id: session.id, - created_at: session.created_at, - updated_at: session.updated_at, - title: undefined, - }; -} - -export function filterVisibleSessions(sessions: SessionSummaryResponse[]) { - const fiveMinutesAgo = Date.now() - 5 * 60 * 1000; - return sessions.filter((session) => { - const hasBeenUpdated = session.updated_at !== session.created_at; - - if (hasBeenUpdated) return true; - - const isRecentlyCreated = - new Date(session.created_at).getTime() > fiveMinutesAgo; - - return isRecentlyCreated; - }); -} - -export function getSessionTitle(session: SessionSummaryResponse) { - if (session.title) return session.title; - - const isNewSession = session.updated_at === session.created_at; - - if (isNewSession) { - const createdDate = new Date(session.created_at); - if (isToday(createdDate)) { - return "Today"; - } - return format(createdDate, "MMM d, yyyy"); - } - - return "Untitled Chat"; -} - -export function getSessionUpdatedLabel(session: SessionSummaryResponse) { - if (!session.updated_at) return ""; - return formatDistanceToNow(new Date(session.updated_at), { addSuffix: true }); -} - -export function mergeCurrentSessionIntoList( - accumulatedSessions: SessionSummaryResponse[], - currentSessionId: string | null, - currentSessionData: SessionDetailResponse | null | undefined, - recentlyCreatedSessions?: Map, -) { - const filteredSessions: SessionSummaryResponse[] = []; - const addedIds = new Set(); - - if (accumulatedSessions.length > 0) { - const visibleSessions = filterVisibleSessions(accumulatedSessions); - - if (currentSessionId) { - const currentInAll = accumulatedSessions.find( - (s) => s.id === currentSessionId, - ); - if (currentInAll) { - const isInVisible = visibleSessions.some( - (s) => s.id === currentSessionId, - ); - if (!isInVisible) { - filteredSessions.push(currentInAll); - addedIds.add(currentInAll.id); - } - } - } - - for (const session of visibleSessions) { - if (!addedIds.has(session.id)) { - filteredSessions.push(session); - addedIds.add(session.id); - } - } - } - - if (currentSessionId && currentSessionData) { - if (!addedIds.has(currentSessionId)) { - const summarySession = convertSessionDetailToSummary(currentSessionData); - filteredSessions.unshift(summarySession); - addedIds.add(currentSessionId); - } - } - - if (recentlyCreatedSessions) { - for (const [sessionId, sessionData] of recentlyCreatedSessions) { - if (!addedIds.has(sessionId)) { - filteredSessions.unshift(sessionData); - addedIds.add(sessionId); - } - } - } - - return filteredSessions; -} - -export function getCurrentSessionId(searchParams: URLSearchParams) { - return searchParams.get("sessionId"); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useCopilotShell.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useCopilotShell.ts deleted file mode 100644 index 913c4d7ded..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useCopilotShell.ts +++ /dev/null @@ -1,124 +0,0 @@ -"use client"; - -import { - getGetV2GetSessionQueryKey, - getGetV2ListSessionsQueryKey, - useGetV2GetSession, -} from "@/app/api/__generated__/endpoints/chat/chat"; -import { okData } from "@/app/api/helpers"; -import { useChatStore } from "@/components/contextual/Chat/chat-store"; -import { useBreakpoint } from "@/lib/hooks/useBreakpoint"; -import { useSupabase } from "@/lib/supabase/hooks/useSupabase"; -import { useQueryClient } from "@tanstack/react-query"; -import { usePathname, useSearchParams } from "next/navigation"; -import { useCopilotStore } from "../../copilot-page-store"; -import { useCopilotSessionId } from "../../useCopilotSessionId"; -import { useMobileDrawer } from "./components/MobileDrawer/useMobileDrawer"; -import { getCurrentSessionId } from "./helpers"; -import { useShellSessionList } from "./useShellSessionList"; - -export function useCopilotShell() { - const pathname = usePathname(); - const searchParams = useSearchParams(); - const queryClient = useQueryClient(); - const breakpoint = useBreakpoint(); - const { isLoggedIn } = useSupabase(); - const isMobile = - breakpoint === "base" || breakpoint === "sm" || breakpoint === "md"; - - const { urlSessionId, setUrlSessionId } = useCopilotSessionId(); - - const isOnHomepage = pathname === "/copilot"; - const paramSessionId = searchParams.get("sessionId"); - - const { - isDrawerOpen, - handleOpenDrawer, - handleCloseDrawer, - handleDrawerOpenChange, - } = useMobileDrawer(); - - const paginationEnabled = !isMobile || isDrawerOpen || !!paramSessionId; - - const currentSessionId = getCurrentSessionId(searchParams); - - const { data: currentSessionData } = useGetV2GetSession( - currentSessionId || "", - { - query: { - enabled: !!currentSessionId, - select: okData, - }, - }, - ); - - const { - sessions, - isLoading, - isSessionsFetching, - hasNextPage, - fetchNextPage, - resetPagination, - recentlyCreatedSessionsRef, - } = useShellSessionList({ - paginationEnabled, - currentSessionId, - currentSessionData, - isOnHomepage, - paramSessionId, - }); - - const stopStream = useChatStore((s) => s.stopStream); - const isCreatingSession = useCopilotStore((s) => s.isCreatingSession); - - function handleSessionClick(sessionId: string) { - if (sessionId === currentSessionId) return; - - // Stop current stream - SSE reconnection allows resuming later - if (currentSessionId) { - stopStream(currentSessionId); - } - - if (recentlyCreatedSessionsRef.current.has(sessionId)) { - queryClient.invalidateQueries({ - queryKey: getGetV2GetSessionQueryKey(sessionId), - }); - } - setUrlSessionId(sessionId, { shallow: false }); - if (isMobile) handleCloseDrawer(); - } - - function handleNewChatClick() { - // Stop current stream - SSE reconnection allows resuming later - if (currentSessionId) { - stopStream(currentSessionId); - } - - resetPagination(); - queryClient.invalidateQueries({ - queryKey: getGetV2ListSessionsQueryKey(), - }); - setUrlSessionId(null, { shallow: false }); - if (isMobile) handleCloseDrawer(); - } - - return { - isMobile, - isDrawerOpen, - isLoggedIn, - hasActiveSession: - Boolean(currentSessionId) && (!isOnHomepage || Boolean(paramSessionId)), - isLoading: isLoading || isCreatingSession, - isCreatingSession, - sessions, - currentSessionId: urlSessionId, - handleOpenDrawer, - handleCloseDrawer, - handleDrawerOpenChange, - handleNewChatClick, - handleSessionClick, - hasNextPage, - isFetchingNextPage: isSessionsFetching, - fetchNextPage, - }; -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useShellSessionList.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useShellSessionList.ts deleted file mode 100644 index fb39a11096..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/components/CopilotShell/useShellSessionList.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { getGetV2ListSessionsQueryKey } from "@/app/api/__generated__/endpoints/chat/chat"; -import type { SessionDetailResponse } from "@/app/api/__generated__/models/sessionDetailResponse"; -import type { SessionSummaryResponse } from "@/app/api/__generated__/models/sessionSummaryResponse"; -import { useChatStore } from "@/components/contextual/Chat/chat-store"; -import { useQueryClient } from "@tanstack/react-query"; -import { useEffect, useMemo, useRef } from "react"; -import { useSessionsPagination } from "./components/SessionsList/useSessionsPagination"; -import { - convertSessionDetailToSummary, - filterVisibleSessions, - mergeCurrentSessionIntoList, -} from "./helpers"; - -interface UseShellSessionListArgs { - paginationEnabled: boolean; - currentSessionId: string | null; - currentSessionData: SessionDetailResponse | null | undefined; - isOnHomepage: boolean; - paramSessionId: string | null; -} - -export function useShellSessionList({ - paginationEnabled, - currentSessionId, - currentSessionData, - isOnHomepage, - paramSessionId, -}: UseShellSessionListArgs) { - const queryClient = useQueryClient(); - const onStreamComplete = useChatStore((s) => s.onStreamComplete); - - const { - sessions: accumulatedSessions, - isLoading: isSessionsLoading, - isFetching: isSessionsFetching, - hasNextPage, - fetchNextPage, - reset: resetPagination, - } = useSessionsPagination({ - enabled: paginationEnabled, - }); - - const recentlyCreatedSessionsRef = useRef< - Map - >(new Map()); - - useEffect(() => { - if (isOnHomepage && !paramSessionId) { - queryClient.invalidateQueries({ - queryKey: getGetV2ListSessionsQueryKey(), - }); - } - }, [isOnHomepage, paramSessionId, queryClient]); - - useEffect(() => { - if (currentSessionId && currentSessionData) { - const isNewSession = - currentSessionData.updated_at === currentSessionData.created_at; - const isNotInAccumulated = !accumulatedSessions.some( - (s) => s.id === currentSessionId, - ); - if (isNewSession || isNotInAccumulated) { - const summary = convertSessionDetailToSummary(currentSessionData); - recentlyCreatedSessionsRef.current.set(currentSessionId, summary); - } - } - }, [currentSessionId, currentSessionData, accumulatedSessions]); - - useEffect(() => { - for (const sessionId of recentlyCreatedSessionsRef.current.keys()) { - if (accumulatedSessions.some((s) => s.id === sessionId)) { - recentlyCreatedSessionsRef.current.delete(sessionId); - } - } - }, [accumulatedSessions]); - - useEffect(() => { - const unsubscribe = onStreamComplete(() => { - queryClient.invalidateQueries({ - queryKey: getGetV2ListSessionsQueryKey(), - }); - }); - return unsubscribe; - }, [onStreamComplete, queryClient]); - - const sessions = useMemo( - () => - mergeCurrentSessionIntoList( - accumulatedSessions, - currentSessionId, - currentSessionData, - recentlyCreatedSessionsRef.current, - ), - [accumulatedSessions, currentSessionId, currentSessionData], - ); - - const visibleSessions = useMemo( - () => filterVisibleSessions(sessions), - [sessions], - ); - - const isLoading = isSessionsLoading && accumulatedSessions.length === 0; - - return { - sessions: visibleSessions, - isLoading, - isSessionsFetching, - hasNextPage, - fetchNextPage, - resetPagination, - recentlyCreatedSessionsRef, - }; -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/EmptySession/EmptySession.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/EmptySession/EmptySession.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/EmptySession/EmptySession.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/EmptySession/EmptySession.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/EmptySession/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/EmptySession/helpers.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/EmptySession/helpers.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/EmptySession/helpers.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/MobileDrawer/MobileDrawer.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/MobileDrawer/MobileDrawer.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/MobileDrawer/MobileDrawer.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/MobileDrawer/MobileDrawer.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/MobileHeader/MobileHeader.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/MobileHeader/MobileHeader.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/MobileHeader/MobileHeader.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/MobileHeader/MobileHeader.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/MorphingTextAnimation/MorphingTextAnimation.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/MorphingTextAnimation/MorphingTextAnimation.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/MorphingTextAnimation/MorphingTextAnimation.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/MorphingTextAnimation/MorphingTextAnimation.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/OrbitLoader/OrbitLoader.module.css b/autogpt_platform/frontend/src/app/(platform)/copilot/components/OrbitLoader/OrbitLoader.module.css similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/OrbitLoader/OrbitLoader.module.css rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/OrbitLoader/OrbitLoader.module.css diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/OrbitLoader/OrbitLoader.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/OrbitLoader/OrbitLoader.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/OrbitLoader/OrbitLoader.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/OrbitLoader/OrbitLoader.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ProgressBar/ProgressBar.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ProgressBar/ProgressBar.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ProgressBar/ProgressBar.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/ProgressBar/ProgressBar.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/PulseLoader/PulseLoader.module.css b/autogpt_platform/frontend/src/app/(platform)/copilot/components/PulseLoader/PulseLoader.module.css similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/PulseLoader/PulseLoader.module.css rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/PulseLoader/PulseLoader.module.css diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/PulseLoader/PulseLoader.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/PulseLoader/PulseLoader.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/PulseLoader/PulseLoader.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/PulseLoader/PulseLoader.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ToolAccordion/AccordionContent.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ToolAccordion/AccordionContent.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ToolAccordion/AccordionContent.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/ToolAccordion/AccordionContent.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ToolAccordion/ToolAccordion.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ToolAccordion/ToolAccordion.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ToolAccordion/ToolAccordion.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/ToolAccordion/ToolAccordion.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ToolAccordion/useToolAccordion.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/components/ToolAccordion/useToolAccordion.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/components/ToolAccordion/useToolAccordion.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/components/ToolAccordion/useToolAccordion.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/copilot-page-store.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/copilot-page-store.ts deleted file mode 100644 index 9fc97a14e3..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/copilot-page-store.ts +++ /dev/null @@ -1,56 +0,0 @@ -"use client"; - -import { create } from "zustand"; - -interface CopilotStoreState { - isStreaming: boolean; - isSwitchingSession: boolean; - isCreatingSession: boolean; - isInterruptModalOpen: boolean; - pendingAction: (() => void) | null; -} - -interface CopilotStoreActions { - setIsStreaming: (isStreaming: boolean) => void; - setIsSwitchingSession: (isSwitchingSession: boolean) => void; - setIsCreatingSession: (isCreating: boolean) => void; - openInterruptModal: (onConfirm: () => void) => void; - confirmInterrupt: () => void; - cancelInterrupt: () => void; -} - -type CopilotStore = CopilotStoreState & CopilotStoreActions; - -export const useCopilotStore = create((set, get) => ({ - isStreaming: false, - isSwitchingSession: false, - isCreatingSession: false, - isInterruptModalOpen: false, - pendingAction: null, - - setIsStreaming(isStreaming) { - set({ isStreaming }); - }, - - setIsSwitchingSession(isSwitchingSession) { - set({ isSwitchingSession }); - }, - - setIsCreatingSession(isCreatingSession) { - set({ isCreatingSession }); - }, - - openInterruptModal(onConfirm) { - set({ isInterruptModalOpen: true, pendingAction: onConfirm }); - }, - - confirmInterrupt() { - const { pendingAction } = get(); - set({ isInterruptModalOpen: false, pendingAction: null }); - if (pendingAction) pendingAction(); - }, - - cancelInterrupt() { - set({ isInterruptModalOpen: false, pendingAction: null }); - }, -})); diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/helpers.ts deleted file mode 100644 index c6e479f896..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/helpers.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { User } from "@supabase/supabase-js"; - -export function getGreetingName(user?: User | null): string { - if (!user) return "there"; - const metadata = user.user_metadata as Record | undefined; - const fullName = metadata?.full_name; - const name = metadata?.name; - if (typeof fullName === "string" && fullName.trim()) { - return fullName.split(" ")[0]; - } - if (typeof name === "string" && name.trim()) { - return name.split(" ")[0]; - } - if (user.email) { - return user.email.split("@")[0]; - } - return "there"; -} - -export function buildCopilotChatUrl(prompt: string): string { - const trimmed = prompt.trim(); - if (!trimmed) return "/copilot/chat"; - const encoded = encodeURIComponent(trimmed); - return `/copilot/chat?prompt=${encoded}`; -} - -export function getQuickActions(): string[] { - return [ - "I don't know where to start, just ask me stuff", - "I do the same thing every week and it's killing me", - "Help me find where I'm wasting my time", - ]; -} - -export function getInputPlaceholder(width?: number) { - if (!width) return "What's your role and what eats up most of your day?"; - - if (width < 500) { - return "I'm a chef and I hate..."; - } - if (width <= 1080) { - return "What's your role and what eats up most of your day?"; - } - return "What's your role and what eats up most of your day? e.g. 'I'm a recruiter and I hate...'"; -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/helpers/convertChatSessionToUiMessages.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/helpers/convertChatSessionToUiMessages.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/helpers/convertChatSessionToUiMessages.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/helpers/convertChatSessionToUiMessages.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/hooks/useAsymptoticProgress.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/hooks/useAsymptoticProgress.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/hooks/useAsymptoticProgress.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/hooks/useAsymptoticProgress.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/layout.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/layout.tsx deleted file mode 100644 index 876e5accfb..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/layout.tsx +++ /dev/null @@ -1,13 +0,0 @@ -"use client"; -import { FeatureFlagPage } from "@/services/feature-flags/FeatureFlagPage"; -import { Flag } from "@/services/feature-flags/use-get-flag"; -import { type ReactNode } from "react"; -import { CopilotShell } from "./components/CopilotShell/CopilotShell"; - -export default function CopilotLayout({ children }: { children: ReactNode }) { - return ( - - {children} - - ); -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/page.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/page.tsx index 542173a99c..402d139db5 100644 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/page.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/copilot/page.tsx @@ -1,149 +1,67 @@ "use client"; -import { Button } from "@/components/atoms/Button/Button"; -import { Skeleton } from "@/components/atoms/Skeleton/Skeleton"; -import { Text } from "@/components/atoms/Text/Text"; -import { Chat } from "@/components/contextual/Chat/Chat"; -import { ChatInput } from "@/components/contextual/Chat/components/ChatInput/ChatInput"; -import { Dialog } from "@/components/molecules/Dialog/Dialog"; -import { useEffect, useState } from "react"; -import { useCopilotStore } from "./copilot-page-store"; -import { getInputPlaceholder } from "./helpers"; +import { SidebarProvider } from "@/components/ui/sidebar"; +import { ChatContainer } from "./components/ChatContainer/ChatContainer"; +import { ChatSidebar } from "./components/ChatSidebar/ChatSidebar"; +import { MobileDrawer } from "./components/MobileDrawer/MobileDrawer"; +import { MobileHeader } from "./components/MobileHeader/MobileHeader"; import { useCopilotPage } from "./useCopilotPage"; -export default function CopilotPage() { - const { state, handlers } = useCopilotPage(); - const isInterruptModalOpen = useCopilotStore((s) => s.isInterruptModalOpen); - const confirmInterrupt = useCopilotStore((s) => s.confirmInterrupt); - const cancelInterrupt = useCopilotStore((s) => s.cancelInterrupt); - - const [inputPlaceholder, setInputPlaceholder] = useState( - getInputPlaceholder(), - ); - - useEffect(() => { - const handleResize = () => { - setInputPlaceholder(getInputPlaceholder(window.innerWidth)); - }; - - handleResize(); - - window.addEventListener("resize", handleResize); - return () => window.removeEventListener("resize", handleResize); - }, []); - - const { greetingName, quickActions, isLoading, hasSession, initialPrompt } = - state; - +export default function Page() { const { - handleQuickAction, - startChatWithPrompt, - handleSessionNotFound, - handleStreamingChange, - } = handlers; - - if (hasSession) { - return ( -
- - { - if (!open) cancelInterrupt(); - }, - }} - onClose={cancelInterrupt} - > - -
- - The current chat response will be interrupted. Are you sure you - want to continue? - - - - - -
-
-
-
- ); - } + sessionId, + messages, + status, + error, + isLoadingSession, + isCreatingSession, + createSession, + onSend, + // Mobile drawer + isMobile, + isDrawerOpen, + sessions, + isLoadingSessions, + handleOpenDrawer, + handleCloseDrawer, + handleDrawerOpenChange, + handleSelectSession, + handleNewChat, + } = useCopilotPage(); return ( -
-
- {isLoading ? ( -
- - -
- -
-
- {Array.from({ length: 4 }).map((_, i) => ( - - ))} -
-
- ) : ( - <> -
- - Hey, {greetingName} - - - Tell me about your work — I'll find what to automate. - - -
- -
-
-
- {quickActions.map((action) => ( - - ))} -
- - )} + + {!isMobile && } +
+ {isMobile && } +
+ +
-
+ {isMobile && ( + + )} + ); } diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/styleguide/page.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/styleguide/page.tsx new file mode 100644 index 0000000000..6030665f1c --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/copilot/styleguide/page.tsx @@ -0,0 +1,1533 @@ +"use client"; + +import { ResponseType } from "@/app/api/__generated__/models/responseType"; +import { + Conversation, + ConversationContent, +} from "@/components/ai-elements/conversation"; +import { + Message, + MessageContent, + MessageResponse, +} from "@/components/ai-elements/message"; +import { Text } from "@/components/atoms/Text/Text"; +import { CopilotChatActionsProvider } from "../components/CopilotChatActionsProvider/CopilotChatActionsProvider"; +import { CreateAgentTool } from "../tools/CreateAgent/CreateAgent"; +import { EditAgentTool } from "../tools/EditAgent/EditAgent"; +import { FindAgentsTool } from "../tools/FindAgents/FindAgents"; +import { FindBlocksTool } from "../tools/FindBlocks/FindBlocks"; +import { RunAgentTool } from "../tools/RunAgent/RunAgent"; +import { RunBlockTool } from "../tools/RunBlock/RunBlock"; +import { SearchDocsTool } from "../tools/SearchDocs/SearchDocs"; +import { ViewAgentOutputTool } from "../tools/ViewAgentOutput/ViewAgentOutput"; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function slugify(text: string) { + return text + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-|-$)/g, ""); +} + +const SECTIONS = [ + "Messages", + "Tool: Find Blocks", + "Tool: Find Agents (Marketplace)", + "Tool: Find Agents (Library)", + "Tool: Search Docs", + "Tool: Get Doc Page", + "Tool: Run Block", + "Tool: Run Agent", + "Tool: Schedule Agent", + "Tool: Create Agent", + "Tool: Edit Agent", + "Tool: View Agent Output", + "Full Conversation Example", +] as const; + +function Section({ + title, + children, +}: { + title: string; + children: React.ReactNode; +}) { + return ( +
+

+ {title} +

+
{children}
+
+ ); +} + +function SubSection({ + label, + children, +}: { + label: string; + children: React.ReactNode; +}) { + return ( +
+

+ {label} +

+ {children} +
+ ); +} + +// --------------------------------------------------------------------------- +// Mock data factories +// --------------------------------------------------------------------------- + +let _id = 0; +function uid() { + return `sg-${++_id}`; +} + +// --------------------------------------------------------------------------- +// Page +// --------------------------------------------------------------------------- + +export default function StyleguidePage() { + return ( + alert(`onSend: ${msg}`)}> +
+ {/* Sidebar */} + + + {/* Content */} +
+
+ Copilot Styleguide +

+ Static showcase of all chat message types, tool states & + variants. +

+ + {/* ============================================================= */} + {/* MESSAGE TYPES */} + {/* ============================================================= */} + +
+ + + + + Find me an agent that can summarize YouTube videos + + + + + + + + + + I found a few agents that can help with YouTube video + summarization. Let me search for the best options for you. + + + + + + + + + + {`Here's what I found:\n\n1. **YouTube Summarizer** — Extracts key points from any YouTube video\n2. **Video Digest** — Creates bullet-point summaries with timestamps\n\n> Both agents support videos up to 2 hours long.\n\n\`\`\`python\n# Example usage\nresult = agent.run(url="https://youtube.com/watch?v=...")\nprint(result.summary)\n\`\`\``} + + + + + + + + + + Thinking... + + + + + + +
+ Error: Connection timed out. Please try again. +
+
+
+ + {/* ============================================================= */} + {/* FIND BLOCKS */} + {/* ============================================================= */} + +
+ + + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* FIND AGENTS (Marketplace) */} + {/* ============================================================= */} + +
+ + + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* FIND AGENTS (Library) */} + {/* ============================================================= */} + +
+ + + + + + + +
+ + {/* ============================================================= */} + {/* SEARCH DOCS */} + {/* ============================================================= */} + +
+ + + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* GET DOC PAGE */} + {/* ============================================================= */} + +
+ + + + + + + +
+ + {/* ============================================================= */} + {/* RUN BLOCK */} + {/* ============================================================= */} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overall, this was our strongest quarter to date.\n\n| Metric | Q3 | Q4 | Change |\n|--------|-----|-----|--------|\n| Revenue | $2.1M | $2.6M | +23% |\n| Users | 10k | 20k | +100% |\n| NPS | 72 | 78 | +6 |", + ], + }, + }, + }} + /> + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* RUN AGENT */} + {/* ============================================================= */} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* SCHEDULE AGENT */} + {/* ============================================================= */} + +
+ + + + + + + +
+ + {/* ============================================================= */} + {/* CREATE AGENT */} + {/* ============================================================= */} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* EDIT AGENT */} + {/* ============================================================= */} + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* VIEW AGENT OUTPUT */} + {/* ============================================================= */} + +
+ + + + + + + + + + AI is not replacing doctors — it's augmenting their capabilities.\n\n### Adoption by Region\n\n| Region | Adoption Rate | Growth |\n|--------|--------------|--------|\n| North America | 78% | +15% |\n| Europe | 62% | +22% |\n| Asia Pacific | 71% | +31% |", + ], + metadata: [ + { + sources_analyzed: 142, + confidence_score: 0.94, + processing_time_ms: 3420, + model_version: "v2.3.1", + categories: [ + "healthcare", + "machine-learning", + "diagnostics", + ], + }, + ], + chart: [ + "https://picsum.photos/seed/chart-demo/500/300", + ], + }, + }, + }, + }} + /> + + + + + + + + + + + + + + + + + +
+ + {/* ============================================================= */} + {/* FULL CONVERSATION EXAMPLE */} + {/* ============================================================= */} + +
+ + + + + + Find me a block that can fetch weather data + + + + + + + + Let me search for weather-related blocks for you. + + + + + + I found 2 blocks related to weather. The **Get Weather** + block fetches current conditions, while **Weather + Forecast** provides a 5-day outlook. Would you like me + to run one of these? + + + + + + + + Yes, run the Get Weather block for San Francisco + + + + + + + + + + The current weather in San Francisco is **68°F** and + **Foggy** with 85% humidity and winds from the west at + 12 mph. + + + + + +
+
+
+
+
+ ); +} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/CreateAgent/CreateAgent.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/CreateAgent/CreateAgent.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/CreateAgent/CreateAgent.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/CreateAgent/CreateAgent.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/CreateAgent/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/CreateAgent/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/CreateAgent/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/CreateAgent/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/EditAgent/EditAgent.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/EditAgent/EditAgent.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/EditAgent/EditAgent.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/EditAgent/EditAgent.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/EditAgent/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/EditAgent/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/EditAgent/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/EditAgent/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindAgents/FindAgents.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindAgents/FindAgents.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindAgents/FindAgents.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindAgents/FindAgents.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindAgents/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindAgents/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindAgents/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindAgents/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindBlocks/FindBlocks.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindBlocks/FindBlocks.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindBlocks/FindBlocks.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindBlocks/FindBlocks.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindBlocks/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindBlocks/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/FindBlocks/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/FindBlocks/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/RunAgent.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/RunAgent.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/RunAgent.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/RunAgent.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/AgentDetailsCard/AgentDetailsCard.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/AgentDetailsCard.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/AgentDetailsCard/AgentDetailsCard.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/AgentDetailsCard.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/AgentDetailsCard/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/helpers.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/AgentDetailsCard/helpers.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/AgentDetailsCard/helpers.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/ErrorCard/ErrorCard.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/ErrorCard/ErrorCard.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/ErrorCard/ErrorCard.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/ErrorCard/ErrorCard.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/ExecutionStartedCard/ExecutionStartedCard.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/ExecutionStartedCard/ExecutionStartedCard.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/ExecutionStartedCard/ExecutionStartedCard.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/ExecutionStartedCard/ExecutionStartedCard.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/SetupRequirementsCard/SetupRequirementsCard.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/SetupRequirementsCard/SetupRequirementsCard.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/SetupRequirementsCard/SetupRequirementsCard.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/SetupRequirementsCard/SetupRequirementsCard.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/SetupRequirementsCard/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/SetupRequirementsCard/helpers.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/components/SetupRequirementsCard/helpers.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/components/SetupRequirementsCard/helpers.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunAgent/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunAgent/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/RunBlock.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/RunBlock.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/RunBlock.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/RunBlock.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/BlockOutputCard/BlockOutputCard.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/BlockOutputCard/BlockOutputCard.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/BlockOutputCard/BlockOutputCard.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/BlockOutputCard/BlockOutputCard.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/ErrorCard/ErrorCard.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/ErrorCard/ErrorCard.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/ErrorCard/ErrorCard.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/ErrorCard/ErrorCard.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/SetupRequirementsCard/SetupRequirementsCard.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/SetupRequirementsCard/SetupRequirementsCard.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/SetupRequirementsCard/SetupRequirementsCard.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/SetupRequirementsCard/SetupRequirementsCard.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/SetupRequirementsCard/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/SetupRequirementsCard/helpers.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/components/SetupRequirementsCard/helpers.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/components/SetupRequirementsCard/helpers.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/RunBlock/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/RunBlock/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/SearchDocs/SearchDocs.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/SearchDocs/SearchDocs.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/SearchDocs/SearchDocs.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/SearchDocs/SearchDocs.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/SearchDocs/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/SearchDocs/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/SearchDocs/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/SearchDocs/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/ViewAgentOutput/ViewAgentOutput.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/ViewAgentOutput/ViewAgentOutput.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/ViewAgentOutput/ViewAgentOutput.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/ViewAgentOutput/ViewAgentOutput.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/ViewAgentOutput/helpers.tsx b/autogpt_platform/frontend/src/app/(platform)/copilot/tools/ViewAgentOutput/helpers.tsx similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/tools/ViewAgentOutput/helpers.tsx rename to autogpt_platform/frontend/src/app/(platform)/copilot/tools/ViewAgentOutput/helpers.tsx diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot-2/useChatSession.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/useChatSession.ts similarity index 100% rename from autogpt_platform/frontend/src/app/(platform)/copilot-2/useChatSession.ts rename to autogpt_platform/frontend/src/app/(platform)/copilot/useChatSession.ts diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts index 9d99f8e7bd..4e2f24e1c1 100644 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts +++ b/autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotPage.ts @@ -1,127 +1,137 @@ -import { - getGetV2ListSessionsQueryKey, - postV2CreateSession, -} from "@/app/api/__generated__/endpoints/chat/chat"; -import { useToast } from "@/components/molecules/Toast/use-toast"; -import { useSupabase } from "@/lib/supabase/hooks/useSupabase"; -import { useOnboarding } from "@/providers/onboarding/onboarding-provider"; -import { SessionKey, sessionStorage } from "@/services/storage/session-storage"; -import * as Sentry from "@sentry/nextjs"; -import { useQueryClient } from "@tanstack/react-query"; -import { useRouter } from "next/navigation"; -import { useEffect } from "react"; -import { useCopilotStore } from "./copilot-page-store"; -import { getGreetingName, getQuickActions } from "./helpers"; -import { useCopilotSessionId } from "./useCopilotSessionId"; +import { useGetV2ListSessions } from "@/app/api/__generated__/endpoints/chat/chat"; +import { useBreakpoint } from "@/lib/hooks/useBreakpoint"; +import { useChat } from "@ai-sdk/react"; +import { DefaultChatTransport } from "ai"; +import { useCallback, useEffect, useState } from "react"; +import { useChatSession } from "./useChatSession"; export function useCopilotPage() { - const router = useRouter(); - const queryClient = useQueryClient(); - const { user, isLoggedIn, isUserLoading } = useSupabase(); - const { toast } = useToast(); - const { completeStep } = useOnboarding(); + const [isDrawerOpen, setIsDrawerOpen] = useState(false); + const [pendingMessage, setPendingMessage] = useState(null); - const { urlSessionId, setUrlSessionId } = useCopilotSessionId(); - const setIsStreaming = useCopilotStore((s) => s.setIsStreaming); - const isCreating = useCopilotStore((s) => s.isCreatingSession); - const setIsCreating = useCopilotStore((s) => s.setIsCreatingSession); + const { + sessionId, + setSessionId, + hydratedMessages, + isLoadingSession, + createSession, + isCreatingSession, + } = useChatSession(); - const greetingName = getGreetingName(user); - const quickActions = getQuickActions(); + const breakpoint = useBreakpoint(); + const isMobile = + breakpoint === "base" || breakpoint === "sm" || breakpoint === "md"; - const hasSession = Boolean(urlSessionId); - const initialPrompt = urlSessionId - ? getInitialPrompt(urlSessionId) - : undefined; + const transport = sessionId + ? new DefaultChatTransport({ + api: `/api/chat/sessions/${sessionId}/stream`, + prepareSendMessagesRequest: ({ messages }) => { + const last = messages[messages.length - 1]; + return { + body: { + message: last.parts + ?.map((p) => (p.type === "text" ? p.text : "")) + .join(""), + is_user_message: last.role === "user", + context: null, + }, + }; + }, + // Resume uses GET on the same endpoint (no message param → backend resumes) + prepareReconnectToStreamRequest: () => ({ + api: `/api/chat/sessions/${sessionId}/stream`, + }), + }) + : null; + + const { messages, sendMessage, status, error, setMessages } = useChat({ + id: sessionId ?? undefined, + transport: transport ?? undefined, + resume: !!sessionId, + }); useEffect(() => { - if (isLoggedIn) completeStep("VISIT_COPILOT"); - }, [completeStep, isLoggedIn]); + if (!hydratedMessages || hydratedMessages.length === 0) return; + setMessages((prev) => { + if (prev.length > hydratedMessages.length) return prev; + return hydratedMessages; + }); + }, [hydratedMessages, setMessages]); - async function startChatWithPrompt(prompt: string) { - if (!prompt?.trim()) return; - if (isCreating) return; + // Clear messages when session is null + useEffect(() => { + if (!sessionId) setMessages([]); + }, [sessionId, setMessages]); - const trimmedPrompt = prompt.trim(); - setIsCreating(true); + useEffect(() => { + if (!sessionId || !pendingMessage) return; + const msg = pendingMessage; + setPendingMessage(null); + sendMessage({ text: msg }); + }, [sessionId, pendingMessage, sendMessage]); - try { - const sessionResponse = await postV2CreateSession({ - body: JSON.stringify({}), - }); + async function onSend(message: string) { + const trimmed = message.trim(); + if (!trimmed) return; - if (sessionResponse.status !== 200 || !sessionResponse.data?.id) { - throw new Error("Failed to create session"); - } - - const sessionId = sessionResponse.data.id; - setInitialPrompt(sessionId, trimmedPrompt); - - await queryClient.invalidateQueries({ - queryKey: getGetV2ListSessionsQueryKey(), - }); - - await setUrlSessionId(sessionId, { shallow: true }); - } catch (error) { - console.error("[CopilotPage] Failed to start chat:", error); - toast({ title: "Failed to start chat", variant: "destructive" }); - Sentry.captureException(error); - } finally { - setIsCreating(false); + if (sessionId) { + sendMessage({ text: trimmed }); + return; } + + setPendingMessage(trimmed); + await createSession(); } - function handleQuickAction(action: string) { - startChatWithPrompt(action); - } + const { data: sessionsResponse, isLoading: isLoadingSessions } = + useGetV2ListSessions({ limit: 50 }); - function handleSessionNotFound() { - router.replace("/copilot"); - } + const sessions = + sessionsResponse?.status === 200 ? sessionsResponse.data.sessions : []; - function handleStreamingChange(isStreamingValue: boolean) { - setIsStreaming(isStreamingValue); - } + const handleOpenDrawer = useCallback(() => { + setIsDrawerOpen(true); + }, []); + + const handleCloseDrawer = useCallback(() => { + setIsDrawerOpen(false); + }, []); + + const handleDrawerOpenChange = useCallback((open: boolean) => { + setIsDrawerOpen(open); + }, []); + + const handleSelectSession = useCallback( + (id: string) => { + setSessionId(id); + if (isMobile) setIsDrawerOpen(false); + }, + [setSessionId, isMobile], + ); + + const handleNewChat = useCallback(() => { + setSessionId(null); + if (isMobile) setIsDrawerOpen(false); + }, [setSessionId, isMobile]); return { - state: { - greetingName, - quickActions, - isLoading: isUserLoading, - hasSession, - initialPrompt, - }, - handlers: { - handleQuickAction, - startChatWithPrompt, - handleSessionNotFound, - handleStreamingChange, - }, + sessionId, + messages, + status, + error, + isLoadingSession, + isCreatingSession, + createSession, + onSend, + // Mobile drawer + isMobile, + isDrawerOpen, + sessions, + isLoadingSessions, + handleOpenDrawer, + handleCloseDrawer, + handleDrawerOpenChange, + handleSelectSession, + handleNewChat, }; } - -function getInitialPrompt(sessionId: string): string | undefined { - try { - const prompts = JSON.parse( - sessionStorage.get(SessionKey.CHAT_INITIAL_PROMPTS) || "{}", - ); - return prompts[sessionId]; - } catch { - return undefined; - } -} - -function setInitialPrompt(sessionId: string, prompt: string): void { - try { - const prompts = JSON.parse( - sessionStorage.get(SessionKey.CHAT_INITIAL_PROMPTS) || "{}", - ); - prompts[sessionId] = prompt; - sessionStorage.set( - SessionKey.CHAT_INITIAL_PROMPTS, - JSON.stringify(prompts), - ); - } catch { - // Ignore storage errors - } -} diff --git a/autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotSessionId.ts b/autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotSessionId.ts deleted file mode 100644 index 87f9b7d3ae..0000000000 --- a/autogpt_platform/frontend/src/app/(platform)/copilot/useCopilotSessionId.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { parseAsString, useQueryState } from "nuqs"; - -export function useCopilotSessionId() { - const [urlSessionId, setUrlSessionId] = useQueryState( - "sessionId", - parseAsString, - ); - - return { urlSessionId, setUrlSessionId }; -}