From eda62dfe7ab0fb01a78c05cf23b3b59c58e188a5 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 31 Jul 2024 15:23:04 -0300 Subject: [PATCH] Zeta AI improvements (#415) --- src/app/api/chat/route.ts | 6 +++--- src/components/Cmdk/components/Cmdk.tsx | 8 +++++++- src/components/Cmdk/components/CmdkChat.tsx | 7 ++++--- .../Cmdk/components/MarkdownMesage.tsx | 20 +++++++++++++++---- src/components/Cmdk/components/ZetaAiIcon.tsx | 8 +++++--- .../components/Layout/components/Layout.tsx | 7 +++++-- .../Layout/components/NavigationLayout.tsx | 15 +++++++++++++- src/lib/ai.constants.ts | 10 ++++++++++ src/pages/_app.tsx | 2 +- 9 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 src/lib/ai.constants.ts diff --git a/src/app/api/chat/route.ts b/src/app/api/chat/route.ts index 81b50c5f..6bdfab3c 100644 --- a/src/app/api/chat/route.ts +++ b/src/app/api/chat/route.ts @@ -4,6 +4,7 @@ import { Ratelimit } from "@upstash/ratelimit"; import { kv } from "@vercel/kv"; import { CoreMessage, embed, streamText } from "ai"; +import { inputSchema } from "~/lib/ai.constants"; import { supabaseClient } from "~/lib/supabase/client"; const getPrompt = ( @@ -62,8 +63,7 @@ export async function POST(req: Request) { }); } - const { messages: _messages } = await req.json(); - const messages = _messages as CoreMessage[]; + const { messages } = inputSchema.parse(await req.json()); const userPrompt = messages[messages.length - 1].content; @@ -100,6 +100,6 @@ export async function POST(req: Request) { } catch (error) { console.error(error); - return new Response("Internal Server Error", { status: 500 }); + return new Response("Zeta AI had an error processing your request, please try asking again.", { status: 500 }); } } diff --git a/src/components/Cmdk/components/Cmdk.tsx b/src/components/Cmdk/components/Cmdk.tsx index b711700f..f1112e95 100644 --- a/src/components/Cmdk/components/Cmdk.tsx +++ b/src/components/Cmdk/components/Cmdk.tsx @@ -250,7 +250,13 @@ export const Cmdk: React.FC = ({ isOpen, setIsCmdkOpen }) => { setIsCmdkOpen={setIsCmdkOpen} /> )} - {activePage === "chat" && } + {activePage === "chat" && ( + setIsCmdkOpen(false)} + initialValue={inputValue} + setCmdkInputValue={setInputValue} + /> + )} diff --git a/src/components/Cmdk/components/CmdkChat.tsx b/src/components/Cmdk/components/CmdkChat.tsx index ec4d41d6..bc1ae3d7 100644 --- a/src/components/Cmdk/components/CmdkChat.tsx +++ b/src/components/Cmdk/components/CmdkChat.tsx @@ -25,7 +25,7 @@ const AssistantMessage: React.FC<{ children: React.ReactNode; className?: string ); }; -export const CmdkChat: React.FC = ({ initialValue, setCmdkInputValue }) => { +export const CmdkChat: React.FC = ({ closeCmdk, initialValue, setCmdkInputValue }) => { const inputRef = useRef(null); const basePath = process.env.NEXT_PUBLIC_BASE_PATH && typeof window !== "undefined" @@ -87,14 +87,14 @@ export const CmdkChat: React.FC = ({ initialValue, setCmdkInputVa className={clsx(index === messages.length - 1 && "mb-8")} messageClasses={message.content.length < 90 ? "flex items-center" : undefined} > - + ); default: return (
- +
); @@ -183,6 +183,7 @@ export const CmdkChat: React.FC = ({ initialValue, setCmdkInputVa }; interface CmdkChatProps { + closeCmdk: () => void; initialValue: string; setCmdkInputValue: React.Dispatch>; } diff --git a/src/components/Cmdk/components/MarkdownMesage.tsx b/src/components/Cmdk/components/MarkdownMesage.tsx index a68e81db..99117bf9 100644 --- a/src/components/Cmdk/components/MarkdownMesage.tsx +++ b/src/components/Cmdk/components/MarkdownMesage.tsx @@ -1,16 +1,19 @@ import { Message } from "ai"; import clsx from "clsx"; +import Link from "next/link"; import React from "react"; import Markdown from "react-markdown"; import rehypeRaw from "rehype-raw"; import remarkGfm from "remark-gfm"; +import { basePath } from "~/lib/app.constants"; + import { MarkdownCodeBlock } from "./MarkdownCodeBlock"; const remarkPlugins = [[remarkGfm, { singleTilde: false }]]; const rehypePlugins = [rehypeRaw]; -export const MarkdownMessage: React.FC = ({ message }) => { +export const MarkdownMessage: React.FC = ({ closeCmdk, message }) => { return ( = ({ message }) => {children} ), - a: ({ children, ...args }) => { + a: ({ children, ref, ...args }) => { + if (typeof args.href !== "string") return null; + const isAbsoluteHref = args.href?.startsWith("http"); + return ( - + {children} - + ); }, // img: (props: any) => NextImageHandler(props), @@ -86,5 +97,6 @@ export const MarkdownMessage: React.FC = ({ message }) => }; interface MarkdownMessageProps { + closeCmdk: () => void; message: Message; } diff --git a/src/components/Cmdk/components/ZetaAiIcon.tsx b/src/components/Cmdk/components/ZetaAiIcon.tsx index 2b239c3a..cc5ffcef 100644 --- a/src/components/Cmdk/components/ZetaAiIcon.tsx +++ b/src/components/Cmdk/components/ZetaAiIcon.tsx @@ -1,10 +1,10 @@ import React from "react"; -export const ZetaAiIcon: React.FC = ({ className }) => { +export const ZetaAiIcon: React.FC = ({ className, width, height }) => { return ( = ({ className }) => { interface ZetaAiIconProps { className?: string; + height?: string; + width?: string; } diff --git a/src/components/shared/components/Layout/components/Layout.tsx b/src/components/shared/components/Layout/components/Layout.tsx index 68f8076d..12eabff2 100644 --- a/src/components/shared/components/Layout/components/Layout.tsx +++ b/src/components/shared/components/Layout/components/Layout.tsx @@ -187,9 +187,10 @@ const LayoutContainer = styled.div<{ isMainPage: boolean }>` type LayoutProps = { className?: string; + setIsCmdkOpen: React.Dispatch>; }; -export const Layout: React.FC> = ({ className, children }) => { +export const Layout: React.FC> = ({ className, children, setIsCmdkOpen }) => { const { route } = useRouter(); const isMainPage = useMemo(() => mainNavRoutes.includes(route), [route]); @@ -201,7 +202,9 @@ export const Layout: React.FC> = ({ className, ch return ( {!isMounted &&
} - {children} + + {children} + ); }; diff --git a/src/components/shared/components/Layout/components/NavigationLayout.tsx b/src/components/shared/components/Layout/components/NavigationLayout.tsx index 07cdb62e..1ed940d4 100644 --- a/src/components/shared/components/Layout/components/NavigationLayout.tsx +++ b/src/components/shared/components/Layout/components/NavigationLayout.tsx @@ -1,3 +1,4 @@ +import { ListItem } from "@mui/material"; import Divider from "@mui/material/Divider"; import List from "@mui/material/List"; import clsx from "clsx"; @@ -5,6 +6,7 @@ import { motion } from "framer-motion"; import Link from "next/link"; import { PropsWithChildren, useEffect, useMemo, useState } from "react"; +import { ZetaAiIcon } from "~/components/Cmdk/components/ZetaAiIcon"; import { useCurrentBreakpoint } from "~/hooks/useCurrentBreakpoint"; import { getRevealProps } from "~/lib/helpers/animations"; @@ -17,6 +19,7 @@ import { NavigationItem } from "./NavigationItem"; type NavigationLayoutProps = PropsWithChildren<{ isMainPage: boolean; + setIsCmdkOpen: React.Dispatch>; }>; const mainLayoutAnimationVariants = { @@ -43,7 +46,7 @@ const leftDrawerAnimationVariants = { }, }; -export const NavigationLayout: React.FC = ({ isMainPage, children }) => { +export const NavigationLayout: React.FC = ({ isMainPage, children, setIsCmdkOpen }) => { const { upSm } = useCurrentBreakpoint(); const [isLeftDrawerOpen, setIsLeftDrawerOpen] = useState(true); @@ -132,6 +135,16 @@ export const NavigationLayout: React.FC = ({ isMainPage,
+ + + {navBottomItems.map((item) => ( - +