diff --git a/ai_course_bot/.gitignore b/ai_course_bot/.gitignore deleted file mode 100644 index fab5a495..00000000 --- a/ai_course_bot/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ai-chatbot-model/state_of_the_union.txt \ No newline at end of file diff --git a/ai_course_bot/ai-chatbot/.env.example b/ai_course_bot/ai-chatbot/.env.example deleted file mode 100644 index ff3c27ae..00000000 --- a/ai_course_bot/ai-chatbot/.env.example +++ /dev/null @@ -1,24 +0,0 @@ -# You must first activate a Billing Account here: https://platform.openai.com/account/billing/overview -# Then get your OpenAI API Key here: https://platform.openai.com/account/api-keys -OPENAI_API_KEY=XXXXXXXX - -# Generate a random secret: https://generate-secret.vercel.app/32 or `openssl rand -base64 32` -AUTH_SECRET=XXXXXXXX -# Create a GitHub OAuth app here: https://github.com/settings/applications/new -# For info on authorization callback URL visit here: https://authjs.dev/reference/core/providers_github#callback-url -AUTH_GITHUB_ID=XXXXXXXX -AUTH_GITHUB_SECRET=XXXXXXXX -# Support OAuth login on preview deployments, see: https://authjs.dev/guides/basics/deployment#securing-a-preview-deployment -# Set the following only when deployed. In this example, we can reuse the same OAuth app, but if you are storing users, we recommend using a different OAuth app for development/production so that you don't mix your test and production user base. -# AUTH_REDIRECT_PROXY_URL=https://YOURAPP.vercel.app/api/auth - -# Instructions to create kv database here: https://vercel.com/docs/storage/vercel-kv/quickstart and -KV_URL=XXXXXXXX -KV_REST_API_URL=XXXXXXXX -KV_REST_API_TOKEN=XXXXXXXX -KV_REST_API_READ_ONLY_TOKEN=XXXXXXXX - -SECURE_JWT_CS_61A=XXXXXXX -SECURE_JWT_CS_DATA8=XXXXXXXX -SECURE_JWT_CS_ROAR=XXXXXXX - diff --git a/ai_course_bot/ai-chatbot/.eslintrc.json b/ai_course_bot/ai-chatbot/.eslintrc.json deleted file mode 100644 index c17b5320..00000000 --- a/ai_course_bot/ai-chatbot/.eslintrc.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/eslintrc", - "root": true, - "extends": [ - "next/core-web-vitals", - "prettier", - "plugin:tailwindcss/recommended" - ], - "plugins": ["tailwindcss"], - "rules": { - "tailwindcss/no-custom-classname": "off", - "tailwindcss/classnames-order": "off" - }, - "settings": { - "tailwindcss": { - "callees": ["cn", "cva"], - "config": "tailwind.config.js" - } - }, - "overrides": [ - { - "files": ["*.ts", "*.tsx"], - "parser": "@typescript-eslint/parser" - } - ] -} diff --git a/ai_course_bot/ai-chatbot/.gitignore b/ai_course_bot/ai-chatbot/.gitignore deleted file mode 100644 index dd019e40..00000000 --- a/ai_course_bot/ai-chatbot/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -node_modules -.pnp -.pnp.js - -# testing -coverage - -# next.js -.next/ -out/ -build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# turbo -.turbo - -.env -.vercel -.vscode -.env*.local diff --git a/ai_course_bot/ai-chatbot/Dockerfile b/ai_course_bot/ai-chatbot/Dockerfile deleted file mode 100755 index 6663aad3..00000000 --- a/ai_course_bot/ai-chatbot/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -# Use an official Node.js runtime as a parent image -FROM node:18-alpine - -# Set the working directory -WORKDIR /app - -# Copy package.json and package-lock.json (if available) -COPY package*.json ./ - -# Install dependencies -RUN npm install - -# Copy the rest of the application code -COPY . . - -# Build the Next.js application -RUN npm run build - -# Expose the port that your Next.js app runs on -EXPOSE 3000 - -# Define the command to run your Next.js application -CMD ["npm", "run", "start"] -# CMD ["npm", "run", "dev"] diff --git a/ai_course_bot/ai-chatbot/LICENSE b/ai_course_bot/ai-chatbot/LICENSE deleted file mode 100755 index 6c16c29f..00000000 --- a/ai_course_bot/ai-chatbot/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2023 Vercel, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file diff --git a/ai_course_bot/ai-chatbot/README.md b/ai_course_bot/ai-chatbot/README.md deleted file mode 100755 index 9884fa36..00000000 --- a/ai_course_bot/ai-chatbot/README.md +++ /dev/null @@ -1,71 +0,0 @@ - - Next.js 14 and App Router-ready AI chatbot. -

Next.js AI Chatbot

-
- -

- An open-source AI chatbot app template built with Next.js, the Vercel AI SDK, OpenAI, and Vercel KV. -

- -

- Features · - Model Providers · - Deploy Your Own · - Running locally · - Authors -

-
- -## Features - -- [Next.js](https://nextjs.org) App Router -- React Server Components (RSCs), Suspense, and Server Actions -- [Vercel AI SDK](https://sdk.vercel.ai/docs) for streaming chat UI -- Support for OpenAI (default), Anthropic, Cohere, Hugging Face, or custom AI chat models and/or LangChain -- [shadcn/ui](https://ui.shadcn.com) - - Styling with [Tailwind CSS](https://tailwindcss.com) - - [Radix UI](https://radix-ui.com) for headless component primitives - - Icons from [Phosphor Icons](https://phosphoricons.com) -- Chat History, rate limiting, and session storage with [Vercel KV](https://vercel.com/storage/kv) -- [NextAuth.js](https://github.com/nextauthjs/next-auth) for authentication - -## Model Providers - -This template ships with OpenAI `gpt-3.5-turbo` as the default. However, thanks to the [Vercel AI SDK](https://sdk.vercel.ai/docs), you can switch LLM providers to [Anthropic](https://anthropic.com), [Cohere](https://cohere.com/), [Hugging Face](https://huggingface.co), or using [LangChain](https://js.langchain.com) with just a few lines of code. - -## Deploy Your Own - -You can deploy your own version of the Next.js AI Chatbot to Vercel with one click: - -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-title=Next.js+Chat&demo-description=A+full-featured%2C+hackable+Next.js+AI+chatbot+built+by+Vercel+Labs&demo-url=https%3A%2F%2Fchat.vercel.ai%2F&demo-image=%2F%2Fimages.ctfassets.net%2Fe5382hct74si%2F4aVPvWuTmBvzM5cEdRdqeW%2F4234f9baf160f68ffb385a43c3527645%2FCleanShot_2023-06-16_at_17.09.21.png&project-name=Next.js+Chat&repository-name=nextjs-chat&repository-url=https%3A%2F%2Fgithub.com%2Fvercel-labs%2Fai-chatbot&from=templates&skippable-integrations=1&env=OPENAI_API_KEY%2CAUTH_GITHUB_ID%2CAUTH_GITHUB_SECRET%2CAUTH_SECRET&envDescription=How+to+get+these+env+vars&envLink=https%3A%2F%2Fgithub.com%2Fvercel-labs%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&teamCreateStatus=hidden&stores=[{"type":"kv"}]) - -## Creating a KV Database Instance - -Follow the steps outlined in the [quick start guide](https://vercel.com/docs/storage/vercel-kv/quickstart#create-a-kv-database) provided by Vercel. This guide will assist you in creating and configuring your KV database instance on Vercel, enabling your application to interact with it. - -Remember to update your environment variables (`KV_URL`, `KV_REST_API_URL`, `KV_REST_API_TOKEN`, `KV_REST_API_READ_ONLY_TOKEN`) in the `.env` file with the appropriate credentials provided during the KV database setup. - -## Running locally - -You will need to use the environment variables [defined in `.env.example`](.env.example) to run Next.js AI Chatbot. It's recommended you use [Vercel Environment Variables](https://vercel.com/docs/projects/environment-variables) for this, but a `.env` file is all that is necessary. - -> Note: You should not commit your `.env` file or it will expose secrets that will allow others to control access to your various OpenAI and authentication provider accounts. - -1. Install Vercel CLI: `npm i -g vercel` -2. Link local instance with Vercel and GitHub accounts (creates `.vercel` directory): `vercel link` -3. Download your environment variables: `vercel env pull` - -```bash -pnpm install -pnpm dev -``` - -Your app template should now be running on [localhost:3000](http://localhost:3000/). - -## Authors - -This library is created by [Vercel](https://vercel.com) and [Next.js](https://nextjs.org) team members, with contributions from: - -- Jared Palmer ([@jaredpalmer](https://twitter.com/jaredpalmer)) - [Vercel](https://vercel.com) -- Shu Ding ([@shuding\_](https://twitter.com/shuding_)) - [Vercel](https://vercel.com) -- shadcn ([@shadcn](https://twitter.com/shadcn)) - [Vercel](https://vercel.com) diff --git a/ai_course_bot/ai-chatbot/app/api/auth/[...nextauth]/route.ts b/ai_course_bot/ai-chatbot/app/api/auth/[...nextauth]/route.ts deleted file mode 100755 index 8cb196fb..00000000 --- a/ai_course_bot/ai-chatbot/app/api/auth/[...nextauth]/route.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { GET, POST } from '@/tai/utils/auth' -export const runtime = 'edge' diff --git a/ai_course_bot/ai-chatbot/app/api/chat/route.ts b/ai_course_bot/ai-chatbot/app/api/chat/route.ts deleted file mode 100755 index 3d19df4e..00000000 --- a/ai_course_bot/ai-chatbot/app/api/chat/route.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { auth } from '@/tai/utils/auth' -import { kv } from '@vercel/kv' -import { nanoid } from '@/tai/lib/utils' - -export const runtime = 'edge' - -export async function POST(req: Request) { - const json = await req.json() - - const { messages, previewToken } = json - var courseId = messages[messages.length - 1].tool_call_id - - const userId: string = (await auth())?.user.email ?? '' - - if (courseId == null || userId == '') { - courseId = 'default' - } - - var apiHost: string = - courseId === 'CS 294-137' - ? process.env['CS_294_137_BACKEND_HOST'] || 'http://0.0.0.0:9000' - : process.env['ROAR_BACKEND_HOST'] || 'http://0.0.0.0:9000' - - const apiUrl: string = apiHost + '/api/chat/completions' - - try { - var body = JSON.stringify({ - course: courseId, - messages, - temperature: 0.7, - stream: true, - userId: userId - }) - - const apiResponse = await fetch(apiUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: body - }) - - if (apiResponse.ok) { - return new Response(apiResponse.body, { - headers: { 'Content-Type': 'application/json' } - }) - } else { - console.log('[Route.ts] API Response Not Ok') - return new Response('Error fetching data', { status: apiResponse.status }) - } - } catch (error) { - console.log('[Route.ts] Error: ', error) - return new Response( - 'Internal Server Error; Server may be down, Please try again later', - { headers: { 'Content-Type': 'application/json' } } - ) - } -} diff --git a/ai_course_bot/ai-chatbot/app/api/chat/save/route.ts b/ai_course_bot/ai-chatbot/app/api/chat/save/route.ts deleted file mode 100644 index 0a1e675a..00000000 --- a/ai_course_bot/ai-chatbot/app/api/chat/save/route.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { nanoid } from '@/tai/lib/utils' -import { auth } from '@/tai/utils/auth' -import { saveChat } from '@/tai/utils/actions' - -export async function POST(req: Request) { - const json = await req.json() - const userId: string = (await auth())?.user.id ?? nanoid() - const title = json.messages[0].content.substring(0, 100) - await saveChat(title, json.messages, userId, json.id) - return new Response() -} diff --git a/ai_course_bot/ai-chatbot/app/chat/[id]/page.tsx b/ai_course_bot/ai-chatbot/app/chat/[id]/page.tsx deleted file mode 100755 index ddea8f77..00000000 --- a/ai_course_bot/ai-chatbot/app/chat/[id]/page.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { type Metadata } from 'next' -import { notFound, redirect } from 'next/navigation' - -import { auth } from '@/tai/utils/auth' -import { getChat } from '@/tai/utils/actions' -import { Chat } from '@/tai/components/chat' - -export interface ChatPageProps { - params: { - id: string - } -} - -export async function generateMetadata({ - params -}: ChatPageProps): Promise { - const session = await auth() - - if (!session?.user) { - return {} - } - - const chat = await getChat(params.id, session.user.id) - return { - title: chat?.title.toString().slice(0, 50) ?? 'Chat' - } -} - -export default async function ChatPage({ params }: ChatPageProps) { - const session = await auth() - - if (!session?.user) { - redirect(`/sign-in?next=/chat/${params.id}`) - } - - const chat = await getChat(params.id, session.user.id) - - if (!chat) { - notFound() - } - - if (chat?.userId !== session?.user?.id) { - notFound() - } - - return -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/button-scroll-to-bottom.tsx b/ai_course_bot/ai-chatbot/app/core/components/button-scroll-to-bottom.tsx deleted file mode 100755 index dabbd1fc..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/button-scroll-to-bottom.tsx +++ /dev/null @@ -1,34 +0,0 @@ -'use client' - -import * as React from 'react' - -import { cn } from '@/tai/lib/utils' -import { useAtBottom } from '@/tai/lib/hooks/use-at-bottom' -import { Button, type ButtonProps } from '@/tai/components/ui/button' -import { IconArrowDown } from '@/tai/components/ui/icons' - -export function ButtonScrollToBottom({ className, ...props }: ButtonProps) { - const isAtBottom = useAtBottom() - - return ( - - ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat-history.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat-history.tsx deleted file mode 100755 index 2877e8fd..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat-history.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import * as React from 'react' - -import Link from 'next/link' - -import { cn } from '@/tai/lib/utils' -import { SidebarList } from '@/tai/components/sidebar-list' -import { buttonVariants } from '@/tai/components/ui/button' -import { IconPlus } from '@/tai/components/ui/icons' -interface ChatHistoryProps { - userId?: string -} - -export async function ChatHistory({ userId }: ChatHistoryProps) { - return ( -
-
- - - New Chat - -
- - {Array.from({ length: 10 }).map((_, i) => ( -
- ))} -
- } - > - {/* @ts-ignore */} - -
-
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat-list.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat-list.tsx deleted file mode 100755 index ffa76152..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat-list.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { type Message } from 'ai' - -import { Separator } from '@/tai/components/ui/separator' -import { ChatMessage } from '@/tai/components/chat-message' - -export interface ChatList { - messages: Message[] -} - -export function ChatList({ messages }: ChatList) { - if (!messages.length) { - return null - } - - return ( -
- {messages.map((message, index) => ( -
- - {index < messages.length - 1 && ( - - )} -
- ))} -
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat-message-actions.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat-message-actions.tsx deleted file mode 100755 index 34b5fa8c..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat-message-actions.tsx +++ /dev/null @@ -1,40 +0,0 @@ -'use client' - -import { type Message } from 'ai' - -import { Button } from '@/tai/components/ui/button' -import { IconCheck, IconCopy } from '@/tai/components/ui/icons' -import { useCopyToClipboard } from '@/tai/lib/hooks/use-copy-to-clipboard' -import { cn } from '@/tai/lib/utils' - -interface ChatMessageActionsProps extends React.ComponentProps<'div'> { - message: Message -} - -export function ChatMessageActions({ - message, - className, - ...props -}: ChatMessageActionsProps) { - const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 }) - - const onCopy = () => { - if (isCopied) return - copyToClipboard(message.content) - } - - return ( -
- -
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat-message.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat-message.tsx deleted file mode 100755 index 5fd44891..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat-message.tsx +++ /dev/null @@ -1,85 +0,0 @@ -// Inspired by Chatbot-UI and modified to fit the needs of this project -// @see https://github.com/mckaywrigley/chatbot-ui/blob/main/components/Chat/ChatMessage.tsx - -import { Message } from 'ai' -import remarkGfm from 'remark-gfm' -import remarkMath from 'remark-math' - -import Image from 'next/image' -import { cn } from '@/tai/lib/utils' -import { CodeBlock } from '@/tai/components/ui/codeblock' -import { MemoizedReactMarkdown } from '@/tai/components/markdown' -import { IconUser } from '@/tai/components/ui/icons' -import { ChatMessageActions } from '@/tai/components/chat-message-actions' - -export interface ChatMessageProps { - message: Message -} - -export function ChatMessage({ message, ...props }: ChatMessageProps) { - return ( -
-
- {message.role === 'user' ? ( - - ) : ( - logo - )} -
-
- {children}

- }, - code({ node, inline, className, children, ...props }) { - if (children.length) { - if (children[0] == '▍') { - return ( - - ) - } - - children[0] = (children[0] as string).replace('`▍`', '▍') - } - - const match = /language-(\w+)/.exec(className || '') - - if (inline) { - return ( - - {children} - - ) - } - - return ( - - ) - } - }} - > - {message.content} -
- -
-
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat-panel.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat-panel.tsx deleted file mode 100755 index f1b267af..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat-panel.tsx +++ /dev/null @@ -1,110 +0,0 @@ -'use client' -import * as React from 'react' -import { type UseChatHelpers } from 'ai/react' - -import { shareChat } from '@/tai/utils/actions' -import { Button } from '@/tai/components/ui/button' -import { PromptForm } from '@/tai/components/prompt-form' -import { ButtonScrollToBottom } from '@/tai/components/button-scroll-to-bottom' -import { IconRefresh, IconShare, IconStop } from '@/tai/components/ui/icons' -import { FooterText } from '@/tai/components/footer' -import { ChatShareDialog } from '@/tai/components/chat-share-dialog' -import { loadData } from '@/tai/lib/utils' -export interface ChatPanelProps - extends Pick< - UseChatHelpers, - | 'append' - | 'isLoading' - | 'reload' - | 'messages' - | 'stop' - | 'input' - | 'setInput' - > { - id?: string - title?: string -} - -export function ChatPanel({ - id, - title, - isLoading, - stop, - append, - reload, - input, - setInput, - messages -}: ChatPanelProps) { - const [shareDialogOpen, setShareDialogOpen] = React.useState(false) - - return ( -
- -
-
- {isLoading ? ( - - ) : ( - messages?.length >= 2 && ( -
- - {id && title ? ( - <> - - setShareDialogOpen(false)} - shareChat={shareChat} - chat={{ - id, - title, - messages - }} - /> - - ) : null} -
- ) - )} -
-
- { - var data = loadData('selectedCourse') - await append({ - id, - content: value, - role: 'user', - tool_call_id: data, - data: data - }) - }} - input={input} - setInput={setInput} - isLoading={isLoading} - /> - {/* */} - -
-
-
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat-scroll-anchor.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat-scroll-anchor.tsx deleted file mode 100755 index bb42555b..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat-scroll-anchor.tsx +++ /dev/null @@ -1,29 +0,0 @@ -'use client' - -import * as React from 'react' -import { useInView } from 'react-intersection-observer' - -import { useAtBottom } from '@/tai/lib/hooks/use-at-bottom' - -interface ChatScrollAnchorProps { - trackVisibility?: boolean -} - -export function ChatScrollAnchor({ trackVisibility }: ChatScrollAnchorProps) { - const isAtBottom = useAtBottom() - const { ref, entry, inView } = useInView({ - trackVisibility, - delay: 100, - rootMargin: '0px 0px -150px 0px' - }) - - React.useEffect(() => { - if (isAtBottom && trackVisibility && !inView) { - entry?.target.scrollIntoView({ - block: 'start' - }) - } - }, [inView, entry, isAtBottom, trackVisibility]) - - return
-} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat-share-dialog.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat-share-dialog.tsx deleted file mode 100755 index 8c74e239..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat-share-dialog.tsx +++ /dev/null @@ -1,106 +0,0 @@ -'use client' - -import * as React from 'react' -import { type DialogProps } from '@radix-ui/react-dialog' -import { toast } from 'react-hot-toast' - -import { ServerActionResult, type Chat } from '@/tai/lib/types' -import { Button } from '@/tai/components/ui/button' -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle -} from '@/tai/components/ui/dialog' -import { IconSpinner } from '@/tai/components/ui/icons' -import { useCopyToClipboard } from '@/tai/lib/hooks/use-copy-to-clipboard' - -interface ChatShareDialogProps extends DialogProps { - chat: Pick - shareChat: (id: string) => ServerActionResult - onCopy: () => void -} - -export function ChatShareDialog({ - chat, - shareChat, - onCopy, - ...props -}: ChatShareDialogProps) { - const { copyToClipboard } = useCopyToClipboard({ timeout: 1000 }) - const [isSharePending, startShareTransition] = React.useTransition() - - const copyShareLink = React.useCallback( - async (chat: Chat) => { - if (!chat.sharePath) { - return toast.error('Could not copy share link to clipboard') - } - - const url = new URL(window.location.href) - url.pathname = chat.sharePath - copyToClipboard(url.toString()) - onCopy() - toast.success('Share link copied to clipboard', { - style: { - borderRadius: '10px', - background: '#333', - color: '#fff', - fontSize: '14px' - }, - iconTheme: { - primary: 'white', - secondary: 'black' - } - }) - }, - [copyToClipboard, onCopy] - ) - - return ( - - - - Share link to chat - - Anyone with the URL will be able to view the shared chat. - - -
-
{chat.title}
-
- {chat.messages.length} messages -
-
- - - -
-
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/chat.tsx b/ai_course_bot/ai-chatbot/app/core/components/chat.tsx deleted file mode 100755 index 9ada1d68..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/chat.tsx +++ /dev/null @@ -1,132 +0,0 @@ -'use client' - -import { useChat, type Message } from 'ai/react' - -import { cn } from '@/tai/lib/utils' -import { ChatList } from '@/tai/components/chat-list' -import { ChatPanel } from '@/tai/components/chat-panel' -import { EmptyScreen } from '@/tai/components/empty-screen' -import { ChatScrollAnchor } from '@/tai/components/chat-scroll-anchor' -import { useLocalStorage } from '@/tai/lib/hooks/use-local-storage' -import { toast } from 'react-hot-toast' -import { usePathname, useRouter } from 'next/navigation' -import { SelectCourse } from '@/tai/components/select-course' -import { useSession } from 'next-auth/react' -import emitter from '@/tai/utils/eventEmitter' - -const IS_PREVIEW = process.env.VERCEL_ENV === 'preview' -export interface ChatProps extends React.ComponentProps<'div'> { - initialMessages?: Message[] - id?: string -} - -export function Chat({ id, initialMessages, className }: ChatProps) { - const { data: session, status } = useSession() - - const router = useRouter() - const path = usePathname() - const [previewToken, setPreviewToken] = useLocalStorage( - 'ai-token', - null - ) - - const saveChat = async ( - prev_messages: Message[], - input: string, - assistant: Message, - id: string | undefined - ) => { - try { - let messages = prev_messages.map(message => { - return { - role: message.role, - content: message.content - } - }) - - messages.push({ - role: 'user', - content: input - }) - - messages.push({ - role: 'assistant', - content: assistant.content - }) - - const response = await fetch('/api/chat/save', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - id, - messages - }) - }) - - if (!response.ok) { - throw new Error('Failed to save chat') - } - - if (!path.includes('chat')) { - window.history.replaceState({}, '', `/chat/${id}`) - router.replace(`/chat/${id}`) - setTimeout(() => { - emitter.emit('historyUpdated') - }, 2000) - } - } catch (error) { - console.error('Error saving chat:', error) - } - } - - const { messages, append, reload, stop, isLoading, input, setInput } = - useChat({ - api: '/api/chat', - initialMessages, - id, - body: { - id, - previewToken - }, - onResponse(response) { - if (response.status === 401) { - toast.error(response.statusText) - } - }, - onFinish(message: Message) { - saveChat(messages, input, message, id) - } - }) - return ( - <> -
-
- {status === 'authenticated' && } -
- - {messages.length ? ( - <> - - - - ) : ( - - )} -
- - - ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/clear-history.tsx b/ai_course_bot/ai-chatbot/app/core/components/clear-history.tsx deleted file mode 100755 index 9e86e5b7..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/clear-history.tsx +++ /dev/null @@ -1,80 +0,0 @@ -'use client' - -import * as React from 'react' -import { useRouter } from 'next/navigation' -import { toast } from 'react-hot-toast' - -import { ServerActionResult } from '@/tai/lib/types' -import { Button } from '@/tai/components/ui/button' -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger -} from '@/tai/components/ui/alert-dialog' -import { IconSpinner } from '@/tai/components/ui/icons' -import { error } from 'console' - -interface ClearHistoryProps { - isEnabled: boolean - clearChats: () => ServerActionResult -} - -export function ClearHistory({ - isEnabled = false, - clearChats -}: ClearHistoryProps) { - const [open, setOpen] = React.useState(false) - const [isPending, startTransition] = React.useTransition() - const router = useRouter() - - return ( - - - - - - - Are you absolutely sure? - - This will permanently delete your chat history and remove your data - from our servers. - - - - Cancel - { - event.preventDefault() - startTransition(() => { - clearChats().then(result => { - if (result && 'error' in result) { - toast.error(result.error) - return - } - - setOpen(false) - - // router.push('/') - window.location.href = '/' - }) - }) - }} - > - {isPending && } - Delete - - - - - ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/empty-screen.tsx b/ai_course_bot/ai-chatbot/app/core/components/empty-screen.tsx deleted file mode 100755 index b7ab6d59..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/empty-screen.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { UseChatHelpers } from 'ai/react' - -import { Button } from '@/tai/components/ui/button' -import { ExternalLink } from '@/tai/components/external-link' -import { IconArrowRight } from '@/tai/components/ui/icons' -import Image from 'next/image' - -const exampleMessages = [ - { - heading: 'Explain course grading system', - message: `What is grading like in this course?` - }, - { - heading: 'Summarize course content', - message: 'Summarize what will I learn in this course \n' - } -] - -export function EmptyScreen({ setInput }: Pick) { - return ( -
-
-
- logo -
-

- Welcome to Teaching Assistant Intelligence -

-

- • You may chat with our public GPT server while remaining anonymous. -

-
- -

- • For Berkeley users with valid campus accounts, you may authenticate - and then chat with private GPT servers that cover teaching assistance - for all supported Berkeley courses. -

-
- -

- • Your questions and private information will never be shared to any - third-party businesses. -

- {/*
- {exampleMessages.map((message, index) => ( - - ))} -
*/} -
-
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/external-link.tsx b/ai_course_bot/ai-chatbot/app/core/components/external-link.tsx deleted file mode 100755 index ba6cc016..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/external-link.tsx +++ /dev/null @@ -1,29 +0,0 @@ -export function ExternalLink({ - href, - children -}: { - href: string - children: React.ReactNode -}) { - return ( - - {children} - - - ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/footer.tsx b/ai_course_bot/ai-chatbot/app/core/components/footer.tsx deleted file mode 100755 index 0a0c1611..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/footer.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' - -import { cn } from '@/tai/lib/utils' -import { ExternalLink } from '@/tai/components/external-link' - -export function FooterText({ className, ...props }: React.ComponentProps<'p'>) { - return ( -

- - This project is fully open sourced on Github - -

- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/header.tsx b/ai_course_bot/ai-chatbot/app/core/components/header.tsx deleted file mode 100755 index 58c69109..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/header.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react' -import Link from 'next/link' -import { cn } from '@/tai/lib/utils' -import { auth } from '@/tai/utils/auth' -import { Button, buttonVariants } from '@/tai/components/ui/button' -import { IconNextChat, IconSeparator } from '@/tai/components/ui/icons' -import { UserMenu } from '@/tai/components/user-menu' -import { SidebarMobile } from './sidebar-mobile' -import { SidebarToggle } from './sidebar-toggle' -import { ChatHistory } from './chat-history' -import { LoginButton } from '@/tai/components/login-button' -import Image from 'next/image' - -async function UserOrLogin() { - const session = await auth() - return ( - <> - {session?.user ? ( - <> - - - - - - ) : ( - - {/* logo */} - {/* - */} - - )} -
- - {session?.user ? : } -
- - ) -} - -export function Header() { - return ( -
-
- }> - - -
-
- logo -
-
- ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/login-button.tsx b/ai_course_bot/ai-chatbot/app/core/components/login-button.tsx deleted file mode 100755 index 08b934f9..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/login-button.tsx +++ /dev/null @@ -1,42 +0,0 @@ -'use client' - -import * as React from 'react' -import { signIn } from 'next-auth/react' - -import { cn } from '@/tai/lib/utils' -import { Button, type ButtonProps } from '@/tai/components/ui/button' -import { IconSpinner, IconGoogle } from '@/tai/components/ui/icons' - -interface LoginButtonProps extends ButtonProps { - showGoogleIcon?: boolean - text?: string -} - -export function LoginButton({ - text = 'Berkeley Account Login', - showGoogleIcon = false, - className, - ...props -}: LoginButtonProps) { - const [isLoading, setIsLoading] = React.useState(false) - return ( - - ) -} diff --git a/ai_course_bot/ai-chatbot/app/core/components/markdown.tsx b/ai_course_bot/ai-chatbot/app/core/components/markdown.tsx deleted file mode 100755 index d4491467..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/markdown.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { FC, memo } from 'react' -import ReactMarkdown, { Options } from 'react-markdown' - -export const MemoizedReactMarkdown: FC = memo( - ReactMarkdown, - (prevProps, nextProps) => - prevProps.children === nextProps.children && - prevProps.className === nextProps.className -) diff --git a/ai_course_bot/ai-chatbot/app/core/components/prompt-form.tsx b/ai_course_bot/ai-chatbot/app/core/components/prompt-form.tsx deleted file mode 100755 index 918ca142..00000000 --- a/ai_course_bot/ai-chatbot/app/core/components/prompt-form.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import * as React from 'react' -import Textarea from 'react-textarea-autosize' -import { UseChatHelpers } from 'ai/react' -import { useEnterSubmit } from '@/tai/lib/hooks/use-enter-submit' -import { cn } from '@/tai/lib/utils' -import { Button, buttonVariants } from '@/tai/components/ui/button' -import { - Tooltip, - TooltipContent, - TooltipTrigger -} from '@/tai/components/ui/tooltip' -import { IconArrowElbow, IconPlus } from '@/tai/components/ui/icons' -import { useRouter } from 'next/navigation' - -export interface PromptProps - extends Pick { - onSubmit: (value: string) => void - isLoading: boolean -} - -export function PromptForm({ - onSubmit, - input, - setInput, - isLoading -}: PromptProps) { - const { formRef, onKeyDown } = useEnterSubmit() - const inputRef = React.useRef(null) - const router = useRouter() - React.useEffect(() => { - if (inputRef.current) { - inputRef.current.focus() - } - }, []) - - return ( -
{ - e.preventDefault() - if (!input?.trim()) { - return - } - setInput('') - await onSubmit(input) - }} - ref={formRef} - > -
- - - - - New Chat - -