package updates

This commit is contained in:
Walter Korman 2025-03-14 19:00:22 -07:00
parent 90e1c8368e
commit a7706aeaca
10 changed files with 1938 additions and 1733 deletions

View file

@ -1,3 +1,6 @@
# Get your xAI API Key here for chat models: https://console.x.ai/
XAI_API_KEY=****
# Get your OpenAI API Key here for chat models: https://platform.openai.com/account/api-keys
OPENAI_API_KEY=****

View file

@ -23,7 +23,7 @@
- [AI SDK](https://sdk.vercel.ai/docs)
- Unified API for generating text, structured objects, and tool calls with LLMs
- Hooks for building dynamic chat and generative user interfaces
- Supports OpenAI (default), Anthropic, Cohere, and other model providers
- Supports xAI (default), OpenAI, Fireworks, and other model providers
- [shadcn/ui](https://ui.shadcn.com)
- Styling with [Tailwind CSS](https://tailwindcss.com)
- Component primitives from [Radix UI](https://radix-ui.com) for accessibility and flexibility
@ -35,19 +35,19 @@
## Model Providers
This template ships with OpenAI `gpt-4o` as the default. However, with the [AI SDK](https://sdk.vercel.ai/docs), you can switch LLM providers to [OpenAI](https://openai.com), [Anthropic](https://anthropic.com), [Cohere](https://cohere.com/), and [many more](https://sdk.vercel.ai/providers/ai-sdk-providers) with just a few lines of code.
This template ships with [xAI](https://x.ai) `grok-2-1212` as the default chat model. However, with the [AI SDK](https://sdk.vercel.ai/docs), you can switch LLM providers to [OpenAI](https://openai.com), [Anthropic](https://anthropic.com), [Cohere](https://cohere.com/), and [many more](https://sdk.vercel.ai/providers/ai-sdk-providers) 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?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=[{%22type%22:%22postgres%22},{%22type%22:%22blob%22}])
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY,XAI_API_KEY,FIREWORKS_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=[{%22type%22:%22postgres%22},{%22type%22:%22blob%22}])
## 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.
> Note: You should not commit your `.env` file or it will expose secrets that will allow others to control access to your various AI 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`

View file

@ -1,17 +1,17 @@
'use client';
"use client";
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useWindowSize } from 'usehooks-ts';
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useWindowSize } from "usehooks-ts";
import { ModelSelector } from '@/components/model-selector';
import { SidebarToggle } from '@/components/sidebar-toggle';
import { Button } from '@/components/ui/button';
import { PlusIcon, VercelIcon } from './icons';
import { useSidebar } from './ui/sidebar';
import { memo } from 'react';
import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip';
import { VisibilityType, VisibilitySelector } from './visibility-selector';
import { ModelSelector } from "@/components/model-selector";
import { SidebarToggle } from "@/components/sidebar-toggle";
import { Button } from "@/components/ui/button";
import { PlusIcon, VercelIcon } from "./icons";
import { useSidebar } from "./ui/sidebar";
import { memo } from "react";
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
import { VisibilityType, VisibilitySelector } from "./visibility-selector";
function PureChatHeader({
chatId,
@ -40,7 +40,7 @@ function PureChatHeader({
variant="outline"
className="order-2 md:order-1 md:px-2 px-2 md:h-fit ml-auto md:ml-0"
onClick={() => {
router.push('/');
router.push("/");
router.refresh();
}}
>
@ -72,7 +72,7 @@ function PureChatHeader({
asChild
>
<Link
href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=%5B%7B%22type%22:%22postgres%22%7D,%7B%22type%22:%22blob%22%7D%5D"
href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY,XAI_API_KEY,FIREWORKS_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=%5B%7B%22type%22:%22postgres%22%7D,%7B%22type%22:%22blob%22%7D%5D"
target="_noblank"
>
<VercelIcon size={16} />

View file

@ -5,7 +5,7 @@ export const BotIcon = () => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width="16"
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -25,7 +25,7 @@ export const UserIcon = () => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width="16"
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -44,7 +44,7 @@ export const AttachmentIcon = () => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width="16"
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -63,7 +63,7 @@ export const VercelIcon = ({ size = 17 }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -82,7 +82,7 @@ export const GitIcon = () => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width="16"
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<g clipPath="url(#clip0_872_3147)">
<path
@ -108,7 +108,7 @@ export const BoxIcon = ({ size = 16 }: { size: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -127,7 +127,7 @@ export const HomeIcon = ({ size = 16 }: { size: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -146,7 +146,7 @@ export const GPSIcon = ({ size = 16 }: { size: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
d="M1 6L15 1L10 15L7.65955 8.91482C7.55797 8.65073 7.34927 8.44203 7.08518 8.34045L1 6Z"
@ -167,7 +167,7 @@ export const InvoiceIcon = ({ size = 16 }: { size: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -186,7 +186,7 @@ export const LogoOpenAI = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
d="M14.9449 6.54871C15.3128 5.45919 15.1861 4.26567 14.5978 3.27464C13.7131 1.75461 11.9345 0.972595 10.1974 1.3406C9.42464 0.481584 8.3144 -0.00692594 7.15045 7.42132e-05C5.37487 -0.00392587 3.79946 1.1241 3.2532 2.79113C2.11256 3.02164 1.12799 3.72615 0.551837 4.72468C-0.339497 6.24071 -0.1363 8.15175 1.05451 9.45178C0.686626 10.5413 0.813308 11.7348 1.40162 12.7258C2.28637 14.2459 4.06498 15.0279 5.80204 14.6599C6.5743 15.5189 7.68504 16.0074 8.849 15.9999C10.6256 16.0044 12.2015 14.8754 12.7478 13.2069C13.8884 12.9764 14.873 12.2718 15.4491 11.2733C16.3394 9.75728 16.1357 7.84774 14.9454 6.54771L14.9449 6.54871ZM8.85001 14.9544C8.13907 14.9554 7.45043 14.7099 6.90468 14.2604C6.92951 14.2474 6.97259 14.2239 7.00046 14.2069L10.2293 12.3668C10.3945 12.2743 10.4959 12.1008 10.4949 11.9133V7.42173L11.8595 8.19925C11.8742 8.20625 11.8838 8.22025 11.8858 8.23625V11.9558C11.8838 13.6099 10.5263 14.9509 8.85001 14.9544ZM2.32133 12.2028C1.9651 11.5958 1.8369 10.8843 1.95902 10.1938C1.98284 10.2078 2.02489 10.2333 2.05479 10.2503L5.28366 12.0903C5.44733 12.1848 5.65003 12.1848 5.81421 12.0903L9.75604 9.84429V11.3993C9.75705 11.4153 9.74945 11.4308 9.73678 11.4408L6.47295 13.3004C5.01915 14.1264 3.1625 13.6354 2.32184 12.2028H2.32133ZM1.47155 5.24819C1.82626 4.64017 2.38619 4.17516 3.05305 3.93366C3.05305 3.96116 3.05152 4.00966 3.05152 4.04366V7.72424C3.05051 7.91124 3.15186 8.08475 3.31654 8.17725L7.25838 10.4228L5.89376 11.2003C5.88008 11.2093 5.86285 11.2108 5.84765 11.2043L2.58331 9.34327C1.13255 8.51426 0.63494 6.68272 1.47104 5.24869L1.47155 5.24819ZM12.6834 7.82274L8.74157 5.57669L10.1062 4.79968C10.1199 4.79068 10.1371 4.78918 10.1523 4.79568L13.4166 6.65522C14.8699 7.48373 15.3681 9.31827 14.5284 10.7523C14.1732 11.3593 13.6138 11.8243 12.9474 12.0663V8.27575C12.9489 8.08875 12.8481 7.91574 12.6839 7.82274H12.6834ZM14.0414 5.8057C14.0176 5.7912 13.9756 5.7662 13.9457 5.7492L10.7168 3.90916C10.5531 3.81466 10.3504 3.81466 10.1863 3.90916L6.24442 6.15521V4.60017C6.2434 4.58417 6.251 4.56867 6.26367 4.55867L9.52751 2.70063C10.9813 1.87311 12.84 2.36563 13.6781 3.80066C14.0323 4.40667 14.1605 5.11618 14.0404 5.8057H14.0414ZM5.50257 8.57726L4.13744 7.79974C4.12275 7.79274 4.11312 7.77874 4.11109 7.76274V4.04316C4.11211 2.38713 5.47368 1.0451 7.15197 1.0461C7.86189 1.0461 8.54902 1.2921 9.09476 1.74011C9.06993 1.75311 9.02737 1.77661 8.99899 1.79361L5.77012 3.63365C5.60493 3.72615 5.50358 3.89916 5.50459 4.08666L5.50257 8.57626V8.57726ZM6.24391 7.00022L7.99972 5.9997L9.75553 6.99972V9.00027L7.99972 10.0003L6.24391 9.00027V7.00022Z"
@ -204,7 +204,7 @@ export const LogoGoogle = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
d="M8.15991 6.54543V9.64362H12.4654C12.2763 10.64 11.709 11.4837 10.8581 12.0509L13.4544 14.0655C14.9671 12.6692 15.8399 10.6182 15.8399 8.18188C15.8399 7.61461 15.789 7.06911 15.6944 6.54552L8.15991 6.54543Z"
@ -234,7 +234,7 @@ export const LogoAnthropic = () => {
x="0px"
y="0px"
viewBox="0 0 92.2 65"
style={{ color: 'currentcolor', fill: 'currentcolor' }}
style={{ color: "currentcolor", fill: "currentcolor" }}
width="18px"
height="18px"
>
@ -253,7 +253,7 @@ export const RouteIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -272,7 +272,7 @@ export const FileIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -291,7 +291,7 @@ export const LoaderIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<g clipPath="url(#clip0_2393_1490)">
<path d="M8 0V4" stroke="currentColor" strokeWidth="1.5" />
@ -367,7 +367,7 @@ export const UploadIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -386,7 +386,7 @@ export const MenuIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -405,7 +405,7 @@ export const PencilEditIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -424,7 +424,7 @@ export const CheckedSquare = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -443,7 +443,7 @@ export const UncheckedSquare = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<rect
x="1"
@ -465,7 +465,7 @@ export const MoreIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -484,7 +484,7 @@ export const TrashIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -503,7 +503,7 @@ export const InfoIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -522,7 +522,7 @@ export const ArrowUpIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -540,7 +540,7 @@ export const StopIcon = ({ size = 16 }: { size?: number }) => {
height={size}
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -559,7 +559,7 @@ export const PaperclipIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
className="-rotate-45"
>
<path
@ -579,7 +579,7 @@ export const MoreHorizontalIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -598,7 +598,7 @@ export const MessageIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -616,7 +616,7 @@ export const CrossIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -633,7 +633,7 @@ export const CrossSmallIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -650,7 +650,7 @@ export const UndoIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -667,7 +667,7 @@ export const RedoIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -684,7 +684,7 @@ export const DeltaIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -701,7 +701,7 @@ export const PenIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -718,7 +718,7 @@ export const SummarizeIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -735,7 +735,7 @@ export const SidebarLeftIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -752,7 +752,7 @@ export const PlusIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -769,7 +769,7 @@ export const CopyIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -786,7 +786,7 @@ export const ThumbUpIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -803,7 +803,7 @@ export const ThumbDownIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -820,7 +820,7 @@ export const ChevronDownIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -837,7 +837,7 @@ export const SparklesIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
d="M2.5 0.5V0H3.5V0.5C3.5 1.60457 4.39543 2.5 5.5 2.5H6V3V3.5H5.5C4.39543 3.5 3.5 4.39543 3.5 5.5V6H3H2.5V5.5C2.5 4.39543 1.60457 3.5 0.5 3.5H0V3V2.5H0.5C1.60457 2.5 2.5 1.60457 2.5 0.5Z"
@ -861,7 +861,7 @@ export const CheckCircleFillIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -880,7 +880,7 @@ export const GlobeIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -899,7 +899,7 @@ export const LockIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -918,7 +918,7 @@ export const EyeIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -937,7 +937,7 @@ export const ShareIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -956,7 +956,7 @@ export const CodeIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -975,7 +975,7 @@ export const PlayIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -994,7 +994,7 @@ export const PythonIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
d="M7.90474 0.00013087C7.24499 0.00316291 6.61494 0.0588153 6.06057 0.15584C4.42745 0.441207 4.13094 1.0385 4.13094 2.14002V3.59479H7.9902V4.07971H4.13094H2.68259C1.56099 4.07971 0.578874 4.7465 0.271682 6.01496C-0.0826597 7.4689 -0.0983767 8.37619 0.271682 9.89434C0.546012 11.0244 1.20115 11.8296 2.32276 11.8296H3.64966V10.0856C3.64966 8.82574 4.75179 7.71441 6.06057 7.71441H9.91533C10.9884 7.71441 11.845 6.84056 11.845 5.77472V2.14002C11.845 1.10556 10.9626 0.328487 9.91533 0.15584C9.25237 0.046687 8.56448 -0.00290121 7.90474 0.00013087ZM5.81768 1.17017C6.21631 1.17017 6.54185 1.49742 6.54185 1.89978C6.54185 2.30072 6.21631 2.62494 5.81768 2.62494C5.41761 2.62494 5.09351 2.30072 5.09351 1.89978C5.09351 1.49742 5.41761 1.17017 5.81768 1.17017Z"
@ -1015,7 +1015,7 @@ export const TerminalWindowIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -1034,7 +1034,7 @@ export const TerminalIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -1053,7 +1053,7 @@ export const ClockRewind = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -1072,7 +1072,7 @@ export const LogsIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -1091,7 +1091,7 @@ export const ImageIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -1109,7 +1109,7 @@ export const FullscreenIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -1126,7 +1126,7 @@ export const DownloadIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"
@ -1143,7 +1143,7 @@ export const LineChartIcon = ({ size = 16 }: { size?: number }) => (
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fill="currentColor"
@ -1161,7 +1161,7 @@ export const WarningIcon = ({ size = 16 }: { size?: number }) => {
strokeLinejoin="round"
viewBox="0 0 16 16"
width={size}
style={{ color: 'currentcolor' }}
style={{ color: "currentcolor" }}
>
<path
fillRule="evenodd"

View file

@ -8,11 +8,14 @@ Deploying to [Vercel](https://vercel.com) is the quickest way to get started wit
- Vercel account and [Vercel CLI](https://vercel.com/docs/cli)
- GitHub/GitLab/Bitbucket account
- API Key from [OpenAI](https://platform.openai.com)
- API Keys from three AI model providers:
- [xAI](https://console.x.ai/)
- [OpenAI](https://platform.openai.com/account/api-keys)
- [Fireworks](https://fireworks.ai/account/api-keys)
### Deploy to Vercel
To deploy the chatbot template to Vercel, click this [link](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=%5B%7B%22type%22:%22postgres%22%7D,%7B%22type%22:%22blob%22%7D%5D) to enter the 1-click deploy flow.
To deploy the chatbot template to Vercel, click this [link](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY,XAI_API_KEY,FIREWORKS_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=%5B%7B%22type%22:%22postgres%22%7D,%7B%22type%22:%22blob%22%7D%5D) to enter the 1-click deploy flow.
During the flow, you will be prompted to create and connect to a postgres database and blob store. You will also need to provide environment variables for the application.

View file

@ -1,33 +1,33 @@
# Update Models
The chatbot template ships with [OpenAI](https://sdk.vercel.ai/providers/ai-sdk-providers/openai) as the default model provider. Since the template is powered by the [AI SDK](https://sdk.vercel.ai), which supports [multiple providers](https://sdk.vercel.ai/providers/ai-sdk-providers) out of the box, you can easily switch to another provider of your choice.
The chatbot template ships with [xAI](https://sdk.vercel.ai/providers/ai-sdk-providers/xai) as the default model provider. Since the template is powered by the [AI SDK](https://sdk.vercel.ai), which supports [multiple providers](https://sdk.vercel.ai/providers/ai-sdk-providers) out of the box, you can easily switch to another provider of your choice.
To update the models, you will need to update the custom provider called `myProvider` at `/lib/ai/models.ts` shown below.
```ts
import { customProvider } from "ai";
import { openai } from "@ai-sdk/openai";
import { xai } from "@ai-sdk/xai";
export const myProvider = customProvider({
languageModels: {
"chat-model-small": openai("gpt-4o-mini"),
"chat-model-large": openai("gpt-4o"),
"chat-model-small": xai("grok-2-1212"),
"chat-model-reasoning": wrapLanguageModel({
model: fireworks("accounts/fireworks/models/deepseek-r1"),
middleware: extractReasoningMiddleware({ tagName: "think" }),
}),
"title-model": openai("gpt-4-turbo"),
"artifact-model": openai("gpt-4o-mini"),
"title-model": xai("grok-2-1212"),
"artifact-model": xai("grok-2-1212"),
},
imageModels: {
"small-model": openai.image("dall-e-3"),
"small-model": openai.image("dall-e-2"),
"large-model": openai.image("dall-e-3"),
},
});
```
You can replace the `openai` models with any other provider of your choice. You will need to install the provider library and switch the models accordingly.
You can replace the models with any other provider of your choice. You will need to install the provider library and switch the models accordingly.
For example, if you want to use Anthropic's `claude-3-5-sonnet` model for `chat-model-large`, you can replace the `openai` model with the `anthropic` model as shown below.
For example, if you want to use Anthropic's `claude-3-5-sonnet` model for `chat-model-large`, you can replace the `xai` model with the `anthropic` model as shown below.
```ts
import { customProvider } from "ai";

View file

@ -1,4 +1,4 @@
export const DEFAULT_CHAT_MODEL: string = 'chat-model-small';
export const DEFAULT_CHAT_MODEL: string = "chat-model-small";
interface ChatModel {
id: string;
@ -8,18 +8,13 @@ interface ChatModel {
export const chatModels: Array<ChatModel> = [
{
id: 'chat-model-small',
name: 'Small model',
description: 'Small model for fast, lightweight tasks',
id: "chat-model-small",
name: "Small model",
description: "Small model for fast, lightweight tasks",
},
{
id: 'chat-model-large',
name: 'Large model',
description: 'Large model for complex, multi-step tasks',
},
{
id: 'chat-model-reasoning',
name: 'Reasoning model',
description: 'Uses advanced reasoning',
id: "chat-model-reasoning",
name: "Reasoning model",
description: "Uses advanced reasoning",
},
];

View file

@ -2,40 +2,40 @@ import {
customProvider,
extractReasoningMiddleware,
wrapLanguageModel,
} from 'ai';
import { openai } from '@ai-sdk/openai';
import { fireworks } from '@ai-sdk/fireworks';
import { isTestEnvironment } from '../constants';
} from "ai";
import { openai } from "@ai-sdk/openai";
import { fireworks } from "@ai-sdk/fireworks";
import { xai } from "@ai-sdk/xai";
import { isTestEnvironment } from "../constants";
import {
artifactModel,
chatModel,
reasoningModel,
titleModel,
} from './models.test';
} from "./models.test";
export const myProvider = isTestEnvironment
? customProvider({
languageModels: {
'chat-model-small': chatModel,
'chat-model-large': chatModel,
'chat-model-reasoning': reasoningModel,
'title-model': titleModel,
'artifact-model': artifactModel,
"chat-model-small": chatModel,
"chat-model-large": chatModel,
"chat-model-reasoning": reasoningModel,
"title-model": titleModel,
"artifact-model": artifactModel,
},
})
: customProvider({
languageModels: {
'chat-model-small': openai('gpt-4o-mini'),
'chat-model-large': openai('gpt-4o'),
'chat-model-reasoning': wrapLanguageModel({
model: fireworks('accounts/fireworks/models/deepseek-r1'),
middleware: extractReasoningMiddleware({ tagName: 'think' }),
"chat-model-small": xai("grok-2-1212"),
"chat-model-reasoning": wrapLanguageModel({
model: fireworks("accounts/fireworks/models/deepseek-r1"),
middleware: extractReasoningMiddleware({ tagName: "think" }),
}),
'title-model': openai('gpt-4-turbo'),
'artifact-model': openai('gpt-4o-mini'),
"title-model": xai("grok-2-1212"),
"artifact-model": xai("grok-2-1212"),
},
imageModels: {
'small-model': openai.image('dall-e-2'),
'large-model': openai.image('dall-e-3'),
"small-model": openai.image("dall-e-2"),
"large-model": openai.image("dall-e-3"),
},
});

View file

@ -19,9 +19,10 @@
"test": "export PLAYWRIGHT=True && pnpm exec playwright test --workers=4"
},
"dependencies": {
"@ai-sdk/fireworks": "0.1.16",
"@ai-sdk/openai": "1.2.5",
"@ai-sdk/fireworks": "^0.1.16",
"@ai-sdk/openai": "^1.2.5",
"@ai-sdk/react": "^1.1.23",
"@ai-sdk/xai": "^1.1.15",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-python": "^6.1.6",
"@codemirror/state": "^6.5.0",
@ -103,5 +104,6 @@
"tailwindcss": "^3.4.1",
"tsx": "^4.19.1",
"typescript": "^5.6.3"
}
},
"packageManager": "pnpm@9.12.3"
}

3424
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff