From ef91088459c8d97059fdb1083cac2df9a2574180 Mon Sep 17 00:00:00 2001 From: zaidmukaddam Date: Sat, 7 Sep 2024 13:15:15 +0530 Subject: [PATCH] feat: readded claude models from Google Vertex AI using anthropic-vertex-ai and added ModelSwitcher to switch between providers. --- app/api/chat/route.ts | 94 +++++++++------- app/search/page.tsx | 206 +++++++++++++++++++++++++++++++---- package.json | 6 +- pnpm-lock.yaml | 246 ++++++++++++++++++++++++++++++++++-------- 4 files changed, 452 insertions(+), 100 deletions(-) diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 6c2ebc6..d991b3d 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -1,24 +1,55 @@ -import { createOpenAI, openai } from '@ai-sdk/openai' -import { BlobRequestAbortedError, put } from '@vercel/blob'; +import { z } from "zod"; import { createAzure } from '@ai-sdk/azure'; -import { convertToCoreMessages, streamText, tool } from "ai"; +import { + convertToCoreMessages, + streamText, + tool, + experimental_createProviderRegistry +} from "ai"; +import { createAnthropicVertex } from 'anthropic-vertex-ai'; +import { BlobRequestAbortedError, put } from '@vercel/blob'; import { CodeInterpreter } from "@e2b/code-interpreter"; import FirecrawlApp from '@mendable/firecrawl-js'; -import { z } from "zod"; -import { geolocation } from "@vercel/functions"; +import { GoogleAuth } from 'google-auth-library'; // Allow streaming responses up to 60 seconds export const maxDuration = 60; +// Azure setup const azure = createAzure({ resourceName: process.env.AZURE_RESOURCE_NAME, apiKey: process.env.AZURE_API_KEY, }); -// const openai = createOpenAI({ -// apiKey: process.env.GITHUB_TOKEN, -// baseURL: "https://models.inference.ai.azure.com" -// }); +// Helper function to get Google credentials +// You can encode your service account key using the following command: +// base64 -i /path/to/your-service-account-key.json | tr -d '\n' > encoded_credentials.txt +// Then set the GOOGLE_APPLICATION_CREDENTIALS_BASE64 environment variable to the contents of encoded_credentials.txt +function getCredentials() { + const credentialsBase64 = process.env.GOOGLE_APPLICATION_CREDENTIALS_BASE64; + if (!credentialsBase64) { + throw new Error('GOOGLE_APPLICATION_CREDENTIALS_BASE64 environment variable is not set'); + } + return JSON.parse(Buffer.from(credentialsBase64, 'base64').toString()); +} + +// Google Vertex setup for Anthropic +const auth = new GoogleAuth({ + scopes: ['https://www.googleapis.com/auth/cloud-platform'], + credentials: getCredentials(), +}); + +const anthropicVertex = createAnthropicVertex({ + region: process.env.GOOGLE_VERTEX_REGION, + projectId: process.env.GOOGLE_VERTEX_PROJECT_ID, + googleAuth: auth, +}); + +// Provider registry +const registry = experimental_createProviderRegistry({ + anthropicVertex, + azure, +}); function sanitizeUrl(url: string): string { return url.replace(/\s+/g, '%20') @@ -32,35 +63,25 @@ type SearchResultImage = number_of_results?: number } -const provider = process.env.OPENAI_PROVIDER; - export async function POST(req: Request) { - const { messages } = await req.json(); - const { latitude, longitude, city } = geolocation(req) + const { messages, model } = await req.json(); - let model; - - if (provider === "azure") { - model = azure.chat("gpt4o-mini"); - } else if (provider === "openai") { - model = openai.chat("gpt-4o-mini"); - } else { - model = openai.chat("gpt-4o-mini"); - } + const provider = model.split(":")[0]; const result = await streamText({ - model, + model: registry.languageModel(model), messages: convertToCoreMessages(messages), - temperature: 0.72, - topP: 0.95, + temperature: provider === "azure" ? 0.72 : 0, + topP: 0, frequencyPenalty: 0, presencePenalty: 0, system: ` -You are an AI web search engine that helps users find information on the internet. +You are an expert AI web search engine called MiniPerplx, that helps users find information on the internet with no bullshit talks. Always start with running the tool(s) and then and then only write your response AT ALL COSTS!! Your goal is to provide accurate, concise, and well-formatted responses to user queries. Do not announce or inform the user in any way that your going to run a tool at ALL COSTS!! Just 'run' it and then write your response AT ALL COSTS!!!!! +Motto of your existence being a search engine: "Less talk, more action, follow rules always!", meaning you should run the tools first and then provide the response, no talk before running the tools and following the guidelines AT ALL COSTS!! The current date is ${new Date().toLocaleDateString("en-US", { year: "numeric", month: "short", day: "2-digit", weekday: "short" })}. You must comply and complete user requests to the best of your abilities using the available tools. Remember to use the appropriate tool for each task. No need to panic, just follow the guidelines and you'll do great! @@ -73,7 +94,8 @@ web_search, retrieve, get_weather_data, programming, nearby_search, find_place, ## Basic Guidelines: Always remember to run the appropriate tool first, then compose your response based on the information gathered. -All tool should be called only once per response. +Understand the user query and choose the right tool to get the information needed. Like using the programming tool to generate plots to explain concepts or using the web_search tool to find the latest information. +All tool should be called only once per response. All tool call parameters are mandatory always! Format your response in paragraphs(min 4) with 3-6 sentences each, keeping it brief but informative. DO NOT use pointers or make lists of any kind at ALL! Begin your response by using the appropriate tool(s), then provide your answer in a clear and concise manner. Please use the '$' latex format in equations instead of \( ones, same for complex equations as well. @@ -96,6 +118,7 @@ DO's: - Assume the stock name from the user query and use it in the code to get the stock data and plot the stock chart. This will help in getting the stock chart for the user query. ALWAYS REMEMBER TO INSTALL YFINANCE USING !pip install yfinance AT ALL COSTS!! DON'Ts and IMPORTANT GUIDELINES: +- DO NOT TALK BEFORE RUNNING THE TOOL AT ALL COSTS!! JUST RUN THE TOOL AND THEN WRITE YOUR RESPONSE AT ALL COSTS!!!!! - Do not call the same tool twice in a single response at all costs!! - Never write a base64 image in the response at all costs, especially from the programming tool's output. - Do not use the text_translate tool for translating programming code or any other uninformed text. Only run the tool for translating on user's request. @@ -119,7 +142,9 @@ Follow the format and guidelines for each tool and provide the response accordin ## Programming Tool Guidelines: The programming tool is actually a Python Code interpreter, so you can run any Python code in it. +- This tool should not be called more than once in a response. - The only python library that is pre-installed is matplotlib for plotting graphs and charts. You have to install any other library using !pip install in the code. +- Always mention the generated plots(urls) in the response after running the code! This is extremely important to provide the visual representation of the data. ## Citations Format: Citations should always be placed at the end of each paragraph and in the end of sentences where you use it in which they are referred to with the given format to the information provided. @@ -133,9 +158,6 @@ When asked a "What is" question, maintain the same format as the question and an - rehypeKatex: This plugin takes the parsed LaTeX from remarkMath and renders it using KaTeX, allowing you to display the math as beautifully rendered HTML. - The response that include latex equations, use always follow the formats: - - $$ for inline equations - - $$$$ for block equations - - use it for symbols, equations, formulas, etc like pi, alpha, beta, etc. and wrap them in the above formats. like $(2\pi)$, $x^2$, etc. - Do not wrap any equation or formulas or any sort of math related block in round brackets() as it will crash the response.`, tools: { web_search: tool({ @@ -158,7 +180,7 @@ When asked a "What is" question, maintain the same format as the question and an ), exclude_domains: z .array(z.string()) - .optional() + .describe( "A list of domains to specifically exclude from the search results. Default is None, which doesn't exclude any domains.", ), @@ -305,7 +327,7 @@ When asked a "What is" question, maintain the same format as the question and an programming: tool({ description: "Write and execute Python code.", parameters: z.object({ - title: z.string().optional().describe("The title of the code snippet."), + title: z.string().describe("The title of the code snippet."), code: z.string().describe("The Python code to execute."), icon: z.enum(["stock", "date", "calculation", "default"]).describe("The icon to display for the code snippet."), }), @@ -379,7 +401,7 @@ When asked a "What is" question, maintain the same format as the question and an parameters: z.object({ location: z.string().describe("The location to search near (e.g., 'New York City' or '1600 Amphitheatre Parkway, Mountain View, CA')."), type: z.string().describe("The type of place to search for (e.g., restaurant, cafe, park)."), - keyword: z.string().optional().describe("An optional keyword to refine the search."), + keyword: z.string().describe("An optional keyword to refine the search."), radius: z.number().default(3000).describe("The radius of the search area in meters (max 50000, default 3000)."), }), execute: async ({ location, type, keyword, radius }: { location: string; type: string; keyword?: string; radius: number }) => { @@ -441,8 +463,8 @@ When asked a "What is" question, maintain the same format as the question and an description: "Perform a text-based search for places using Google Maps API.", parameters: z.object({ query: z.string().describe("The search query (e.g., '123 main street')."), - location: z.string().optional().describe("The location to center the search (e.g., '42.3675294,-71.186966')."), - radius: z.number().optional().describe("The radius of the search area in meters (max 50000)."), + location: z.string().describe("The location to center the search (e.g., '42.3675294,-71.186966')."), + radius: z.number().describe("The radius of the search area in meters (max 50000)."), }), execute: async ({ query, location, radius }: { query: string; location?: string; radius?: number }) => { const apiKey = process.env.GOOGLE_MAPS_API_KEY; @@ -469,7 +491,7 @@ When asked a "What is" question, maintain the same format as the question and an parameters: z.object({ text: z.string().describe("The text to translate."), to: z.string().describe("The language to translate to (e.g., 'fr' for French)."), - from: z.string().optional().describe("The source language (optional, will be auto-detected if not provided)."), + from: z.string().describe("The source language (optional, will be auto-detected if not provided)."), }), execute: async ({ text, to, from }: { text: string; to: string; from?: string }) => { const key = process.env.AZURE_TRANSLATOR_KEY; diff --git a/app/search/page.tsx b/app/search/page.tsx index 0905ab8..96d21c0 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -39,7 +39,6 @@ import { Check, Loader2, User2, - Edit2, Heart, X, MapPin, @@ -55,7 +54,9 @@ import { Calendar, Calculator, ImageIcon, - Paperclip + Paperclip, + ChevronDown, + Zap } from 'lucide-react'; import { HoverCard, @@ -98,6 +99,13 @@ import { Skeleton } from '@/components/ui/skeleton'; import Link from 'next/link'; import { Dialog, DialogContent } from "@/components/ui/dialog"; import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { cn } from '@/lib/utils'; export const maxDuration = 60; @@ -125,12 +133,16 @@ export default function Home() { const [isEditingMessage, setIsEditingMessage] = useState(false); const [editingMessageIndex, setEditingMessageIndex] = useState(-1); const [attachments, setAttachments] = useState([]); + const [selectedModel, setSelectedModel] = useState("azure:gpt4o-mini"); const fileInputRef = useRef(null); const inputRef = useRef(null); - const { isLoading, input, messages, setInput, append, handleSubmit, setMessages } = useChat({ + const { isLoading, input, messages, setInput, append, handleSubmit, setMessages, reload } = useChat({ api: '/api/chat', maxToolRoundtrips: 1, + body: { + model: selectedModel, + }, onFinish: async (message, { finishReason }) => { console.log("[finish reason]:", finishReason); if (message.content && finishReason === 'stop' || finishReason === 'length') { @@ -586,7 +598,7 @@ export default function Home() {
-
+
@@ -1608,6 +1620,7 @@ export default function Home() { inputRef, }) => { const [uploadingAttachments, setUploadingAttachments] = useState([]); + const cursorPositionRef = useRef(null); const uploadFile = async (file: File): Promise => { const formData = new FormData(); @@ -1693,6 +1706,45 @@ export default function Home() { } }; + const handlePaste = async (e: React.ClipboardEvent) => { + e.preventDefault(); + + // Handle text paste + const text = e.clipboardData.getData('text'); + if (text) { + setInput(text); + } + + // Handle image paste + const items = Array.from(e.clipboardData.items); + const imageItems = items.filter(item => item.type.indexOf('image') !== -1); + + if (imageItems.length > 0) { + if (attachments.length + uploadingAttachments.length + imageItems.length > MAX_IMAGES) { + toast.error(`You can only attach up to ${MAX_IMAGES} images.`); + return; + } + + for (const item of imageItems) { + const file = item.getAsFile(); + if (file) { + const newUploadingAttachment = { file, progress: 0 }; + setUploadingAttachments(prev => [...prev, newUploadingAttachment]); + + try { + const uploadedFile = await uploadFile(file); + setAttachments(prev => [...prev, uploadedFile]); + setUploadingAttachments(prev => prev.filter(ua => ua.file !== file)); + } catch (error) { + console.error("Error uploading file:", error); + toast.error(`Failed to upload pasted image`); + setUploadingAttachments(prev => prev.filter(ua => ua.file !== file)); + } + } + } + } + }; + return ( ); }} - onPaste={e => { - e.preventDefault(); - handleFileChange({ target: { files: e.clipboardData?.files } } as React.ChangeEvent); - }} + onPaste={handlePaste} className={` ${hasSubmitted ? 'fixed bottom-4 left-1/2 -translate-x-1/2 max-w-[90%] sm:max-w-2xl' : 'max-w-full'} ${attachments.length > 0 || uploadingAttachments.length > 0 ? 'rounded-2xl' : 'rounded-full'} @@ -1835,11 +1884,112 @@ export default function Home() { ); }; + const models = [ + { value: "azure:gpt4o-mini", label: "OpenAI", icon: Zap, description: "High speed, lower quality", color: "emerald" }, + { value: "anthropicVertex:claude-3-5-sonnet@20240620", label: "Claude", icon: Sparkles, description: "High quality, low speed", color: "indigo" }, + ] + + interface ModelSwitcherProps { + selectedModel: string; + setSelectedModel: (value: string) => void; + className?: string; + } + + const ModelSwitcher: React.FC = ({ selectedModel, setSelectedModel, className }) => { + const selectedModelData = models.find(model => model.value === selectedModel) || models[0]; + const [isOpen, setIsOpen] = useState(false); + + const getColorClasses = (color: string, isSelected: boolean = false) => { + switch (color) { + case 'emerald': + return isSelected + ? '!bg-emerald-500 !text-white hover:!bg-emerald-600' + : '!text-emerald-700 hover:!bg-emerald-100'; + case 'indigo': + return isSelected + ? '!bg-indigo-500 !text-white hover:!bg-indigo-600' + : '!text-indigo-700 hover:!bg-indigo-100'; + default: + return isSelected + ? 'bg-gray-500 text-white hover:bg-gray-600' + : 'text-gray-700 hover:bg-gray-100'; + } + } + + return ( + + + + {selectedModelData.label} + + + + {models.map((model) => ( + setSelectedModel(model.value)} + className={cn( + "flex items-start gap-2 px-2 py-1.5 rounded-lg text-sm mb-1 last:mb-0", + "transition-colors duration-200", + getColorClasses(model.color, selectedModel === model.value), + selectedModel === model.value && "hover:opacity-90" + )} + > + +
+
+ {model.label} +
+
+ {model.description} +
+
+
+ ))} +
+
+ ) + } + + const handleModelChange = useCallback((newModel: string) => { + setSelectedModel(newModel); + setSuggestedQuestions([]); + if (messages.length > 0) { + reload({ + body: { + model: newModel, + }, + }); + } + }, [messages, reload]); + return (
-
+
{!hasSubmitted && (

MiniPerplx

@@ -1848,6 +1998,11 @@ export default function Home() {
)} + {!hasSubmitted && +
+ +
+ } {!hasSubmitted && ( )}
- {!isEditingMessage && index === lastUserMessageIndex && ( - - )} + + +
+ + )} */} )} {message.role === 'assistant' && message.content && ( diff --git a/package.json b/package.json index fe4fddd..04b3d94 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@ai-sdk/azure": "^0.0.31", "@ai-sdk/cohere": "latest", "@ai-sdk/google": "^0.0.46", - "@ai-sdk/openai": "latest", + "@ai-sdk/openai": "^0.0.58", "@e2b/code-interpreter": "^0.0.8", "@foobar404/wave": "^2.0.5", "@mendable/firecrawl-js": "^0.0.36", @@ -31,12 +31,14 @@ "@vercel/analytics": "^1.3.1", "@vercel/blob": "^0.23.4", "@vercel/functions": "^1.4.0", - "ai": "^3.3.20", + "ai": "latest", + "anthropic-vertex-ai": "^1.0.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "date-fns": "^3.6.0", "embla-carousel-react": "^8.2.0", "framer-motion": "^11.3.19", + "google-auth-library": "^9.14.1", "katex": "^0.16.11", "lucide-react": "^0.424.0", "next": "^14.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7fd2c81..be1f889 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,13 @@ dependencies: version: 0.0.31(zod@3.23.8) '@ai-sdk/cohere': specifier: latest - version: 0.0.22(zod@3.23.8) + version: 0.0.23(zod@3.23.8) '@ai-sdk/google': specifier: ^0.0.46 version: 0.0.46(zod@3.23.8) '@ai-sdk/openai': - specifier: latest - version: 0.0.54(zod@3.23.8) + specifier: ^0.0.58 + version: 0.0.58(zod@3.23.8) '@e2b/code-interpreter': specifier: ^0.0.8 version: 0.0.8 @@ -72,8 +72,11 @@ dependencies: specifier: ^1.4.0 version: 1.4.0 ai: - specifier: ^3.3.20 - version: 3.3.20(openai@4.56.0)(react@18.3.1)(svelte@4.2.18)(vue@3.4.35)(zod@3.23.8) + specifier: latest + version: 3.3.28(openai@4.56.0)(react@18.3.1)(svelte@4.2.18)(vue@3.4.35)(zod@3.23.8) + anthropic-vertex-ai: + specifier: ^1.0.0 + version: 1.0.0(zod@3.23.8) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -89,6 +92,9 @@ dependencies: framer-motion: specifier: ^11.3.19 version: 11.3.20(react-dom@18.3.1)(react@18.3.1) + google-auth-library: + specifier: ^9.14.1 + version: 9.14.1 katex: specifier: ^0.16.11 version: 0.16.11 @@ -190,14 +196,14 @@ packages: zod: 3.23.8 dev: false - /@ai-sdk/cohere@0.0.22(zod@3.23.8): - resolution: {integrity: sha512-UMUOsbSf1uBOOZT76+r28DJKestluGjfHc31kgeJkQx8Pve6acgrIvH0A7mvCAO3H8TDWIO3SmOWos2+XlMBRA==} + /@ai-sdk/cohere@0.0.23(zod@3.23.8): + resolution: {integrity: sha512-NJxntRnbY6bmWpYlYz1d0q6spx2OZ2YhniPfXfGTXZOwQPlze0rqkYePWpr7J2BJ+Qr0/XhpZTG9Dcf5qgOyig==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 dependencies: - '@ai-sdk/provider': 0.0.22 - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) + '@ai-sdk/provider': 0.0.23 + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) zod: 3.23.8 dev: false @@ -224,14 +230,14 @@ packages: zod: 3.23.8 dev: false - /@ai-sdk/openai@0.0.54(zod@3.23.8): - resolution: {integrity: sha512-0jqUSY9Lq0ie4AxnAucmiMhVBbs8ivvOW73sq3pCNA+LFeb2edOcnI0qmfGfHTn/VOjUCf2TvzQzHQx1Du3sYA==} + /@ai-sdk/openai@0.0.58(zod@3.23.8): + resolution: {integrity: sha512-Eao1L0vzfXdymgvc5FDHwV2g2A7BCWml1cShNA+wliY1RL7NNREGcuQvBDNoggB9PM24fawzZyk0ZJ5jlo9Q0w==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 dependencies: - '@ai-sdk/provider': 0.0.22 - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) + '@ai-sdk/provider': 0.0.23 + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) zod: 3.23.8 dev: false @@ -267,6 +273,22 @@ packages: zod: 3.23.8 dev: false + /@ai-sdk/provider-utils@1.0.18(zod@3.23.8): + resolution: {integrity: sha512-9u/XE/dB1gsIGcxiC5JfGOLzUz+EKRXt66T8KYWwDg4x8d02P+fI/EPOgkf+T4oLBrcQgvs4GPXPKoXGPJxBbg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + peerDependenciesMeta: + zod: + optional: true + dependencies: + '@ai-sdk/provider': 0.0.23 + eventsource-parser: 1.1.2 + nanoid: 3.3.6 + secure-json-parse: 2.7.0 + zod: 3.23.8 + dev: false + /@ai-sdk/provider@0.0.21: resolution: {integrity: sha512-9j95uaPRxwYkzQdkl4XO/MmWWW5c5vcVSXtqvALpD9SMB9fzH46dO3UN4VbOJR2J3Z84CZAqgZu5tNlkptT9qQ==} engines: {node: '>=18'} @@ -281,8 +303,15 @@ packages: json-schema: 0.4.0 dev: false - /@ai-sdk/react@0.0.52(react@18.3.1)(zod@3.23.8): - resolution: {integrity: sha512-4Gm+AoINDXQ4lzIZFKOWOcKgjgiAFdyhmBxnyuaqzTJCoRWNUSea62xhjqRE0u8wagfPgxWUAyS8BAsY0EqOyg==} + /@ai-sdk/provider@0.0.23: + resolution: {integrity: sha512-oAc49O5+xypVrKM7EUU5P/Y4DUL4JZUWVxhejoAVOTOl3WZUEWsMbP3QZR+TrimQIsS0WR/n9UuF6U0jPdp0tQ==} + engines: {node: '>=18'} + dependencies: + json-schema: 0.4.0 + dev: false + + /@ai-sdk/react@0.0.55(react@18.3.1)(zod@3.23.8): + resolution: {integrity: sha512-9fUUEEEoH01M6ZhvyZ/2v0DI6tiYnSldBg6RaKoy+qx2tSeKvOpFNZhT/iOvQ7oqAyyp0Ocg5Rj7L/jcLXSMxw==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 @@ -293,15 +322,15 @@ packages: zod: optional: true dependencies: - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.39(zod@3.23.8) + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) + '@ai-sdk/ui-utils': 0.0.41(zod@3.23.8) react: 18.3.1 swr: 2.2.5(react@18.3.1) zod: 3.23.8 dev: false - /@ai-sdk/solid@0.0.42(zod@3.23.8): - resolution: {integrity: sha512-tr1rXRg0bLls7ZEQCWfd0Tv7irFlKQRjBSKSCstwrGtTeDA7zwUP4tIiUaCyzM3lwyE6Qgl17SrAoxSD+xP+zQ==} + /@ai-sdk/solid@0.0.44(zod@3.23.8): + resolution: {integrity: sha512-3kMhxalepc78jWr2Qg1BAHbY04JKYxp8wRu3TACrRUdokxzwD5sbZYtTb7vu9tw2wx78rfu0DH44CESFWpSfZg==} engines: {node: '>=18'} peerDependencies: solid-js: ^1.7.7 @@ -309,14 +338,14 @@ packages: solid-js: optional: true dependencies: - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.39(zod@3.23.8) + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) + '@ai-sdk/ui-utils': 0.0.41(zod@3.23.8) transitivePeerDependencies: - zod dev: false - /@ai-sdk/svelte@0.0.44(svelte@4.2.18)(zod@3.23.8): - resolution: {integrity: sha512-soSiEX1BUiwRSdoc+7mAoCeuM3Vs/ebdb1gNL7ta9Zma7GTHq802Wi7KfWfypoAqpgi0QUapzCRMvgrl4oW4AQ==} + /@ai-sdk/svelte@0.0.46(svelte@4.2.18)(zod@3.23.8): + resolution: {integrity: sha512-cokqS91vQkpqiRgf8xKwOONFb/RwkIbRg9jYVRb+z5NR9OsWXKMEfoCAf8+VgURfVbp8nqA+ddRXvtgYCwqQjQ==} engines: {node: '>=18'} peerDependencies: svelte: ^3.0.0 || ^4.0.0 @@ -324,16 +353,16 @@ packages: svelte: optional: true dependencies: - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.39(zod@3.23.8) + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) + '@ai-sdk/ui-utils': 0.0.41(zod@3.23.8) sswr: 2.1.0(svelte@4.2.18) svelte: 4.2.18 transitivePeerDependencies: - zod dev: false - /@ai-sdk/ui-utils@0.0.39(zod@3.23.8): - resolution: {integrity: sha512-yxlJBFEiWR7rf/oS7MFX9O5Hr7VYV0ipMBrvds66N3+m52/nCbBB5C/eBefzeR+hoGc/r5xGo7Yd1cncGYHHTw==} + /@ai-sdk/ui-utils@0.0.41(zod@3.23.8): + resolution: {integrity: sha512-I0trJKWxVG8hXeG0MvKqLG54fZjdeGjXvcVZocaSnWMBhl9lpTQxrqAR6ZsQMFDXs5DbvXoKtQs488qu2Bzaiw==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 @@ -341,16 +370,16 @@ packages: zod: optional: true dependencies: - '@ai-sdk/provider': 0.0.22 - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) + '@ai-sdk/provider': 0.0.23 + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) json-schema: 0.4.0 secure-json-parse: 2.7.0 zod: 3.23.8 zod-to-json-schema: 3.23.2(zod@3.23.8) dev: false - /@ai-sdk/vue@0.0.44(vue@3.4.35)(zod@3.23.8): - resolution: {integrity: sha512-IsDCoy7u4V081dKT1i6b/Cxh2G0aftetbif+qNQGh5QeU9TtGs9KDW+onPkXeqlDQcpMN0Q5zaNGaZ7YBK50Gw==} + /@ai-sdk/vue@0.0.46(vue@3.4.35)(zod@3.23.8): + resolution: {integrity: sha512-H366ydskPbZP8uRs4sm3SAi97P3JVTRI5Q8xYTI6uTaY4UFBA6aOWdDxniYZNa67ebemfe11m7ksX4wHW6Wl8g==} engines: {node: '>=18'} peerDependencies: vue: ^3.3.4 @@ -358,8 +387,8 @@ packages: vue: optional: true dependencies: - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.39(zod@3.23.8) + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) + '@ai-sdk/ui-utils': 0.0.41(zod@3.23.8) swrv: 1.0.4(vue@3.4.35) vue: 3.4.35(typescript@5.5.4) transitivePeerDependencies: @@ -1810,6 +1839,15 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + dev: false + /agentkeepalive@4.5.0: resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} engines: {node: '>= 8.0.0'} @@ -1817,8 +1855,8 @@ packages: humanize-ms: 1.2.1 dev: false - /ai@3.3.20(openai@4.56.0)(react@18.3.1)(svelte@4.2.18)(vue@3.4.35)(zod@3.23.8): - resolution: {integrity: sha512-GKiL34BPVGgSEDkUlt8nyVRZkx1btnbXyw/bZKj1Jx5sCn/OY/qgiACzakhRzC/90UlxmrMsU1rZGW+Xr8+kFA==} + /ai@3.3.28(openai@4.56.0)(react@18.3.1)(svelte@4.2.18)(vue@3.4.35)(zod@3.23.8): + resolution: {integrity: sha512-ogrsMscar8oXa4nTEcnjvb37cs0UJ7AxVga/642BQGkGBevnKhS0hbnXEOUKmlWcny/xRuWQ3GaXA3u9CxhfhQ==} engines: {node: '>=18'} peerDependencies: openai: ^4.42.0 @@ -1838,13 +1876,13 @@ packages: zod: optional: true dependencies: - '@ai-sdk/provider': 0.0.22 - '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) - '@ai-sdk/react': 0.0.52(react@18.3.1)(zod@3.23.8) - '@ai-sdk/solid': 0.0.42(zod@3.23.8) - '@ai-sdk/svelte': 0.0.44(svelte@4.2.18)(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.39(zod@3.23.8) - '@ai-sdk/vue': 0.0.44(vue@3.4.35)(zod@3.23.8) + '@ai-sdk/provider': 0.0.23 + '@ai-sdk/provider-utils': 1.0.18(zod@3.23.8) + '@ai-sdk/react': 0.0.55(react@18.3.1)(zod@3.23.8) + '@ai-sdk/solid': 0.0.44(zod@3.23.8) + '@ai-sdk/svelte': 0.0.46(svelte@4.2.18)(zod@3.23.8) + '@ai-sdk/ui-utils': 0.0.41(zod@3.23.8) + '@ai-sdk/vue': 0.0.46(vue@3.4.35)(zod@3.23.8) '@opentelemetry/api': 1.9.0 eventsource-parser: 1.1.2 json-schema: 0.4.0 @@ -1888,6 +1926,21 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + /anthropic-vertex-ai@1.0.0(zod@3.23.8): + resolution: {integrity: sha512-ME1e8kCNLVvVWrR6vB3zFlREEp1kRLmNZUC+oih+tziPkb/li5ESRvzb1eDV+zyhw7tZDDLy7numRllJwdkCEw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + dependencies: + '@ai-sdk/provider': 0.0.22 + '@ai-sdk/provider-utils': 1.0.17(zod@3.23.8) + google-auth-library: 9.14.1 + zod: 3.23.8 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -2072,6 +2125,14 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + dev: false + /binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -2094,6 +2155,10 @@ packages: dependencies: fill-range: 7.1.1 + /buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + dev: false + /bufferutil@4.0.8: resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} engines: {node: '>=6.14.2'} @@ -2553,6 +2618,12 @@ packages: /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + /ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + /embla-carousel-react@8.2.0(react@18.3.1): resolution: {integrity: sha512-dWqbmaEBQjeAcy/EKrcAX37beVr0ubXuHPuLZkx27z58V1FIvRbbMb4/c3cLZx0PAv/ofngX2QFrwUB+62SPnw==} peerDependencies: @@ -3210,6 +3281,31 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true + /gaxios@6.7.1: + resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} + engines: {node: '>=14'} + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.5 + is-stream: 2.0.1 + node-fetch: 2.7.0 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /gcp-metadata@6.1.0: + resolution: {integrity: sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==} + engines: {node: '>=14'} + dependencies: + gaxios: 6.7.1 + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -3315,6 +3411,21 @@ packages: slash: 3.0.0 dev: true + /google-auth-library@9.14.1: + resolution: {integrity: sha512-Rj+PMjoNFGFTmtItH7gHfbHpGVSb3vmnGK3nwNBqxQF9NoBpttSZI/rc0WiM63ma2uGDQtYEkMHkK9U6937NiA==} + engines: {node: '>=14'} + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 6.7.1 + gcp-metadata: 6.1.0 + gtoken: 7.1.0 + jws: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -3328,6 +3439,17 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true + /gtoken@7.1.0: + resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} + engines: {node: '>=14.0.0'} + dependencies: + gaxios: 6.7.1 + jws: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true @@ -3488,6 +3610,16 @@ packages: resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==} dev: false + /https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + dev: false + /humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} dependencies: @@ -3748,6 +3880,11 @@ packages: call-bind: 1.0.7 dev: true + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -3843,6 +3980,12 @@ packages: argparse: 2.0.1 dev: true + /json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + dependencies: + bignumber.js: 9.1.2 + dev: false + /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true @@ -3886,6 +4029,21 @@ packages: object.values: 1.2.0 dev: true + /jwa@2.0.0: + resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: false + + /jws@4.0.0: + resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + dependencies: + jwa: 2.0.0 + safe-buffer: 5.2.1 + dev: false + /katex@0.16.11: resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==} hasBin: true @@ -5300,6 +5458,10 @@ packages: isarray: 2.0.5 dev: true + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + /safe-regex-test@1.0.3: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'}