"use client"; import { useEffect, useRef } from "react"; import { useSession } from "next-auth/react"; import { AssistantRuntimeProvider, useLocalRuntime, type ChatModelAdapter, } from "@assistant-ui/react"; import { Thread } from "@/components/assistant-ui/thread"; interface AtlasChatProps { projectId: string; projectName?: string; } function makeAtlasAdapter(projectId: string): ChatModelAdapter { return { async run({ messages, abortSignal }) { const lastUser = [...messages].reverse().find((m) => m.role === "user"); const text = lastUser?.content .filter((p) => p.type === "text") .map((p) => (p as { type: "text"; text: string }).text) .join("") ?? ""; const res = await fetch(`/api/projects/${projectId}/atlas-chat`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message: text }), signal: abortSignal, }); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.error || "Atlas is unavailable. Please try again."); } const data = await res.json(); return { content: [{ type: "text", text: data.reply || "…" }] }; }, }; } function AtlasChatInner({ projectId, projectName, userInitial, runtime, }: AtlasChatProps & { userInitial: string; runtime: ReturnType; }) { const greeted = useRef(false); useEffect(() => { if (greeted.current) return; greeted.current = true; const opener = `Hey — I'm starting a new project called "${projectName || "my project"}". I'd love your help defining what we're building.`; const t = setTimeout(() => { runtime.thread.composer.setText(opener); runtime.thread.composer.send(); }, 300); return () => clearTimeout(t); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( // No card — fills the layout space directly
); } export function AtlasChat({ projectId, projectName }: AtlasChatProps) { const { data: session } = useSession(); const userInitial = session?.user?.name?.[0]?.toUpperCase() ?? session?.user?.email?.[0]?.toUpperCase() ?? "Y"; const adapter = makeAtlasAdapter(projectId); const runtime = useLocalRuntime(adapter); return ( ); }