"use client"; import { RemoveScroll } from "react-remove-scroll"; import { type ComponentProps, createContext, type SyntheticEvent, use, useEffect, useMemo, useRef, useState, } from "react"; import { Loader2, RefreshCw, SearchIcon, Send, X } from "lucide-react"; import { cn } from "@/lib/utils"; import { buttonVariants } from "fumadocs-ui/components/ui/button"; import Link from "fumadocs-core/link"; import { type UIMessage, useChat, type UseChatHelpers } from "@ai-sdk/react"; import type { ProvideLinksToolSchema } from "@/lib/chat/inkeep-qa-schema"; import type { z } from "zod"; import { DefaultChatTransport } from "ai"; import { Markdown } from "./markdown"; import { Presence } from "@radix-ui/react-presence"; const Context = createContext<{ open: boolean; setOpen: (open: boolean) => void; chat: UseChatHelpers; } | null>(null); function useChatContext() { return use(Context)!.chat; } function SearchAIActions() { const { messages, status, setMessages, regenerate } = useChatContext(); const isLoading = status === "streaming"; if (messages.length === 0) return null; return ( <> {!isLoading && messages.at(-1)?.role === "assistant" && ( )} ); } const suggestions = [ "How do I set up authentication with Better Auth?", "How to integrate Better Auth with NextJs?", "How to add two-factor authentication?", "How to setup SSO with Google?", ]; function SearchAIInput(props: ComponentProps<"form">) { const { status, sendMessage, stop, messages } = useChatContext(); const [input, setInput] = useState(""); const isLoading = status === "streaming" || status === "submitted"; const showSuggestions = messages.length === 0 && !isLoading; const onStart = (e?: SyntheticEvent) => { e?.preventDefault(); void sendMessage({ text: input }); setInput(""); }; const handleSuggestionClick = (suggestion: string) => { setInput(suggestion); void sendMessage({ text: suggestion }); }; useEffect(() => { if (isLoading) document.getElementById("nd-ai-input")?.focus(); }, [isLoading]); return (
{ setInput(e.target.value); }} onKeyDown={(event) => { if (!event.shiftKey && event.key === "Enter") { onStart(event); } }} /> {isLoading ? ( ) : ( )}
{showSuggestions && (

Try asking:

{suggestions.slice(0, 4).map((suggestion, i) => ( ))}
)}
); } function List(props: Omit, "dir">) { const containerRef = useRef(null); useEffect(() => { if (!containerRef.current) return; function callback() { const container = containerRef.current; if (!container) return; container.scrollTo({ top: container.scrollHeight, behavior: "instant", }); } const observer = new ResizeObserver(callback); callback(); const element = containerRef.current?.firstElementChild; if (element) { observer.observe(element); } return () => { observer.disconnect(); }; }, []); return (
{props.children}
); } function Input(props: ComponentProps<"textarea">) { const ref = useRef(null); const shared = cn("col-start-1 row-start-1", props.className); return (