diff --git a/apps/web/src/app/mentor/page.tsx b/apps/web/src/app/mentor/page.tsx index ddd3180..78f6690 100644 --- a/apps/web/src/app/mentor/page.tsx +++ b/apps/web/src/app/mentor/page.tsx @@ -1,11 +1,12 @@ "use client"; -import { useQuery, useMutation } from "@tanstack/react-query"; +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { useEffect, useState } from "react"; import { AppShell } from "@/components/layout/app-shell"; import { MentorChatMessages } from "@/components/features/mentor-chat-messages"; import { createChatSession, fetchChatSessions, useMentorChat } from "@/hooks/useMentorChat"; import Link from "next/link"; +import { MEMORY_CATEGORIES, type MemoryCategory } from "@adventureos/shared"; const SUGGESTED = [ "What should I focus on today?", @@ -16,7 +17,17 @@ const SUGGESTED = [ "What goals am I working towards?", ]; +type MemorySuggestion = { + id: string; + category: string; + title: string; + content: string; + sourceType: string; + confidence: string; +}; + export default function MentorPage() { + const queryClient = useQueryClient(); const [sessionId, setSessionId] = useState(null); const [tab, setTab] = useState<"chat" | "knows" | "preview">("chat"); const [previewInput, setPreviewInput] = useState(""); @@ -28,27 +39,46 @@ export default function MentorPage() { useEffect(() => { if (!sessionId && sessionsData?.sessions?.[0]) { - setSessionId(sessionsData.sessions[0].id); + queueMicrotask(() => setSessionId(sessionsData.sessions[0].id)); } else if (!sessionId) { createChatSession().then((d) => setSessionId(d.id)); } }, [sessionId, sessionsData]); const chat = useMentorChat(sessionId); + const { archiveSuccess, resetArchiveSuccess } = chat; + + const { data: suggestionsData } = useQuery<{ suggestions: MemorySuggestion[] }>({ + queryKey: ["ai-memory-suggestions"], + queryFn: async () => { + const res = await fetch("/api/ai/memory/suggestions"); + if (!res.ok) throw new Error("Failed to load memory suggestions"); + return res.json(); + }, + enabled: tab === "chat", + }); + + const pendingSuggestions = suggestionsData?.suggestions ?? []; + + const refreshMemory = () => { + queryClient.invalidateQueries({ queryKey: ["ai-memory-suggestions"] }); + queryClient.invalidateQueries({ queryKey: ["ai-knows"] }); + queryClient.invalidateQueries({ queryKey: ["context-preview"] }); + }; useEffect(() => { - if (!chat.archiveSuccess || !sessionId) return; - chat.resetArchiveSuccess(); + if (!archiveSuccess || !sessionId) return; + resetArchiveSuccess(); const remaining = (sessionsData?.sessions ?? []).filter( (s: { id: string }) => s.id !== sessionId ); if (remaining.length > 0) { - setSessionId(remaining[0].id); + queueMicrotask(() => setSessionId(remaining[0].id)); } else { createChatSession().then((d) => setSessionId(d.id)); } - }, [chat.archiveSuccess, sessionId, sessionsData, chat.resetArchiveSuccess]); + }, [archiveSuccess, sessionId, sessionsData, resetArchiveSuccess]); const { data: knowsData } = useQuery({ queryKey: ["ai-knows"], @@ -139,6 +169,25 @@ export default function MentorPage() { bottomRef={chat.bottomRef} /> + {pendingSuggestions.length > 0 && ( +
+
+

+ {pendingSuggestions.length} memory suggestion{pendingSuggestions.length === 1 ? "" : "s"} +

+ + Review all + +
+ {pendingSuggestions.slice(0, 2).map((suggestion) => ( + + ))} +
+ )}
{SUGGESTED.map((q) => (