From d2c299350eff0e3f11b5af714d8bf4714c887b47 Mon Sep 17 00:00:00 2001 From: zaidmukaddam Date: Fri, 25 Oct 2024 01:14:58 +0530 Subject: [PATCH] Refactor dependencies and add new features --- app/api/chat/route.ts | 30 +---- app/search/page.tsx | 126 +------------------ components/map-components.tsx | 207 ++++++++++++++++++++++++++++++ components/markdown-render.tsx | 208 +++++++++++++++++++++++++++++++ components/ui/form-component.tsx | 2 +- components/weather-chart.tsx | 118 ++++++++++++++++++ package.json | 4 +- pnpm-lock.yaml | 70 +++++++---- 8 files changed, 590 insertions(+), 175 deletions(-) create mode 100644 components/map-components.tsx create mode 100644 components/markdown-render.tsx create mode 100644 components/weather-chart.tsx diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 8506a08..c1d4eb2 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -1,16 +1,15 @@ import { z } from "zod"; import { createAzure } from '@ai-sdk/azure'; +import { anthropic } from '@ai-sdk/anthropic' 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 { GoogleAuth } from 'google-auth-library'; // Allow streaming responses up to 60 seconds export const maxDuration = 120; @@ -21,33 +20,9 @@ const azure = createAzure({ apiKey: process.env.AZURE_API_KEY, }); -// 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, + anthropic, azure, }); @@ -75,6 +50,7 @@ export async function POST(req: Request) { topP: 0.5, frequencyPenalty: 0, presencePenalty: 0, + experimental_activeTools: ["get_weather_data","programming", "web_search", "text_translate"], system: ` 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!! diff --git a/app/search/page.tsx b/app/search/page.tsx index 3a30cbb..648ff3e 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -123,6 +123,7 @@ import { } from "@/components/ui/table"; import Autoplay from 'embla-carousel-autoplay'; import FormComponent from '@/components/ui/form-component'; +import WeatherChart from '@/components/weather-chart'; export const maxDuration = 60; @@ -320,117 +321,6 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd ); }; - // Weather chart components - - interface WeatherDataPoint { - date: string; - minTemp: number; - maxTemp: number; - } - - const WeatherChart: React.FC<{ result: any }> = React.memo(({ result }) => { - const { chartData, minTemp, maxTemp } = useMemo(() => { - const weatherData: WeatherDataPoint[] = result.list.map((item: any) => ({ - date: new Date(item.dt * 1000).toLocaleDateString(), - minTemp: Number((item.main.temp_min - 273.15).toFixed(1)), - maxTemp: Number((item.main.temp_max - 273.15).toFixed(1)), - })); - - // Group data by date and calculate min and max temperatures - const groupedData: { [key: string]: WeatherDataPoint } = weatherData.reduce((acc, curr) => { - if (!acc[curr.date]) { - acc[curr.date] = { ...curr }; - } else { - acc[curr.date].minTemp = Math.min(acc[curr.date].minTemp, curr.minTemp); - acc[curr.date].maxTemp = Math.max(acc[curr.date].maxTemp, curr.maxTemp); - } - return acc; - }, {} as { [key: string]: WeatherDataPoint }); - - const chartData = Object.values(groupedData); - - // Calculate overall min and max temperatures - const minTemp = Math.min(...chartData.map(d => d.minTemp)); - const maxTemp = Math.max(...chartData.map(d => d.maxTemp)); - - return { chartData, minTemp, maxTemp }; - }, [result]); - - const chartConfig: ChartConfig = useMemo(() => ({ - minTemp: { - label: "Min Temp.", - color: "hsl(var(--chart-1))", - }, - maxTemp: { - label: "Max Temp.", - color: "hsl(var(--chart-2))", - }, - }), []); - - return ( - - - Weather Forecast for {result.city.name} - - Showing min and max temperatures for the next 5 days - - - - - - - - new Date(value).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })} - stroke="#9CA3AF" - /> - `${value}°C`} - stroke="#9CA3AF" - /> - } /> - - - - - - - -
-
-
- {result.city.name}, {result.city.country} -
-
- Next 5 days forecast -
-
-
-
-
- ); - }); - - WeatherChart.displayName = 'WeatherChart'; // Google Maps components @@ -1144,20 +1034,6 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd ); } - - if (isLoading) { - return ( - - - - - -
- - - ); - } - return ; } diff --git a/components/map-components.tsx b/components/map-components.tsx new file mode 100644 index 0000000..93b4e36 --- /dev/null +++ b/components/map-components.tsx @@ -0,0 +1,207 @@ +import React, { useRef, useState, useEffect, useCallback, memo } from 'react'; +import { Card, CardHeader, CardContent, CardTitle } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; +import { MapPin, Star } from 'lucide-react'; +import { Skeleton } from '@/components/ui/skeleton'; + +const isValidCoordinate = (coord: number) => { + return typeof coord === 'number' && !isNaN(coord) && isFinite(coord); +}; + +const loadGoogleMapsScript = (callback: () => void) => { + if (window.google && window.google.maps) { + callback(); + return; + } + + const existingScript = document.getElementById('googleMapsScript'); + if (existingScript) { + existingScript.remove(); + } + + window.initMap = callback; + const script = document.createElement('script'); + script.id = 'googleMapsScript'; + script.src = `https://maps.googleapis.com/maps/api/js?key=${process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}&libraries=places,marker&callback=initMap`; + script.async = true; + script.defer = true; + document.head.appendChild(script); +}; + +const MapComponent = React.memo(({ center, places }: { center: { lat: number; lng: number }, places: any[] }) => { + const mapRef = useRef(null); + const [mapError, setMapError] = useState(null); + const googleMapRef = useRef(null); + const markersRef = useRef([]); + + const initializeMap = useCallback(async () => { + if (mapRef.current && isValidCoordinate(center.lat) && isValidCoordinate(center.lng)) { + const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary; + const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary; + + if (!googleMapRef.current) { + googleMapRef.current = new Map(mapRef.current, { + center: center, + zoom: 14, + mapId: "347ff92e0c7225cf", + }); + } else { + googleMapRef.current.setCenter(center); + } + + markersRef.current.forEach(marker => marker.map = null); + markersRef.current = []; + + places.forEach((place) => { + if (isValidCoordinate(place.location.lat) && isValidCoordinate(place.location.lng)) { + const marker = new AdvancedMarkerElement({ + map: googleMapRef.current, + position: place.location, + title: place.name, + }); + markersRef.current.push(marker); + } + }); + } else { + setMapError('Invalid coordinates provided'); + } + }, [center, places]); + + useEffect(() => { + loadGoogleMapsScript(() => { + try { + initializeMap(); + } catch (error) { + console.error('Error initializing map:', error); + setMapError('Failed to initialize Google Maps'); + } + }); + + return () => { + markersRef.current.forEach(marker => marker.map = null); + }; + }, [initializeMap]); + + if (mapError) { + return
{mapError}
; + } + + return
; +}); + +MapComponent.displayName = 'MapComponent'; + +const MapSkeleton = () => ( + +); + +const PlaceDetails = ({ place }: { place: any }) => ( +
+
+

{place.name}

+

+ {place.vicinity} +

+
+ {place.rating && ( + + + {place.rating} ({place.user_ratings_total}) + + )} +
+); + +const MapEmbed = memo(({ location, zoom = 15 }: { location: string, zoom?: number }) => { + const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY; + const mapUrl = `https://www.google.com/maps/embed/v1/place?key=${apiKey}&q=${encodeURIComponent(location)}&zoom=${zoom}`; + + return ( +
+ +
+ ); +}); + +MapEmbed.displayName = 'MapEmbed'; + +const FindPlaceResult = memo(({ result }: { result: any }) => { + const place = result.candidates[0]; + const location = `${place.geometry.location.lat},${place.geometry.location.lng}`; + + return ( + + + + + {place.name} + + + + +
+

Address: {place.formatted_address}

+ {place.rating && ( +
+ Rating: + + + {place.rating} + +
+ )} + {place.opening_hours && ( +

Open now: {place.opening_hours.open_now ? 'Yes' : 'No'}

+ )} +
+
+
+ ); +}); + +FindPlaceResult.displayName = 'FindPlaceResult'; + +const TextSearchResult = React.memo(({ result }: { result: any }) => { + const centerLocation = result.results[0]?.geometry?.location; + const mapLocation = centerLocation ? `${centerLocation.lat},${centerLocation.lng}` : ''; + + return ( + + + + + Text Search Results + + + + {mapLocation && } + + + Place Details + +
+ {result.results.map((place: any, index: number) => ( + + ))} +
+
+
+
+
+
+ ); +}); + +TextSearchResult.displayName = 'TextSearchResult'; + +export { MapComponent, MapSkeleton, FindPlaceResult, TextSearchResult }; \ No newline at end of file diff --git a/components/markdown-render.tsx b/components/markdown-render.tsx new file mode 100644 index 0000000..67f1415 --- /dev/null +++ b/components/markdown-render.tsx @@ -0,0 +1,208 @@ +import React, { useState, useCallback, useMemo } from 'react'; +import ReactMarkdown from 'react-markdown'; +import Marked, { ReactRenderer } from 'marked-react'; +import SyntaxHighlighter from 'react-syntax-highlighter'; +import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism'; +import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card"; +import { Button } from '@/components/ui/button'; +import { Check, Copy } from 'lucide-react'; +import Image from 'next/image'; +import Link from 'next/link'; +import { fetchMetadata } from '@/app/actions'; + +interface MarkdownRendererProps { + content: string; +} + +interface CitationLink { + text: string; + link: string; +} + +interface LinkMetadata { + title: string; + description: string; +} + +const isValidUrl = (str: string) => { + try { + new URL(str); + return true; + } catch { + return false; + } +}; + +const MarkdownRenderer: React.FC = ({ content }) => { + const [metadataCache, setMetadataCache] = useState>({}); + + const citationLinks = useMemo(() => { + return Array.from(content.matchAll(/\[([^\]]+)\]\(([^)]+)\)/g)).map(([_, text, link]) => ({ + text, + link, + })); + }, [content]); + + const fetchMetadataWithCache = useCallback(async (url: string) => { + if (metadataCache[url]) { + return metadataCache[url]; + } + + const metadata = await fetchMetadata(url); + if (metadata) { + setMetadataCache(prev => ({ ...prev, [url]: metadata })); + } + return metadata; + }, [metadataCache]); + + const CodeBlock = ({ language, children }: { language: string | undefined; children: string }) => { + const [isCopied, setIsCopied] = useState(false); + + const handleCopy = async () => { + await navigator.clipboard.writeText(children); + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); + }; + + return ( +
+ + {children} + + +
+ ); + }; + + const LinkPreview = ({ href }: { href: string }) => { + const [metadata, setMetadata] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + React.useEffect(() => { + setIsLoading(true); + fetchMetadataWithCache(href).then((data) => { + setMetadata(data); + setIsLoading(false); + }); + }, [href]); + + if (isLoading) { + return ( +
+
+
+ ); + } + + const domain = new URL(href).hostname; + + return ( +
+
+ Favicon + {domain} +
+
+

+ {metadata?.title || "Untitled"} +

+ {metadata?.description && ( +

+ {metadata.description} +

+ )} +
+
+ ); + }; + + const renderHoverCard = (href: string, text: React.ReactNode, isCitation: boolean = false) => { + return ( + + + + {text} + + + + + + + ); + }; + + const renderer: Partial = { + paragraph(children) { + return

{children}

; + }, + code(children, language) { + return {String(children)}; + }, + link(href, text) { + const citationIndex = citationLinks.findIndex(link => link.link === href); + if (citationIndex !== -1) { + return ( + + {renderHoverCard(href, citationIndex + 1, true)} + + ); + } + return isValidUrl(href) ? renderHoverCard(href, text) : {text}; + }, + heading(children, level) { + const HeadingTag = `h${level}` as keyof JSX.IntrinsicElements; + const className = `text-${4 - level}xl font-bold my-4 text-neutral-800 dark:text-neutral-100`; + return {children}; + }, + list(children, ordered) { + const ListTag = ordered ? 'ol' : 'ul'; + return {children}; + }, + listItem(children) { + return
  • {children}
  • ; + }, + blockquote(children) { + return
    {children}
    ; + }, + }; + + return ( +
    + {content} +
    + ); +}; + +export default MarkdownRenderer; \ No newline at end of file diff --git a/components/ui/form-component.tsx b/components/ui/form-component.tsx index 3305e01..9931497 100644 --- a/components/ui/form-component.tsx +++ b/components/ui/form-component.tsx @@ -24,7 +24,7 @@ interface ModelSwitcherProps { const models = [ { value: "azure:gpt4o-mini", label: "GPT-4o Mini", icon: Zap, description: "High speed, good quality", color: "emerald" }, - { value: "anthropicVertex:claude-3-5-sonnet@20240620", label: "Claude", icon: Sparkles, description: "High quality, lower speed", color: "indigo" }, + { value: "anthropic:claude-3-5-sonnet-latest", label: "Claude", icon: Sparkles, description: "High quality, lower speed", color: "indigo" }, { value: "azure:gpt-4o", label: "GPT-4o", icon: Cpu, description: "Higher quality, normal speed", color: "blue" }, ]; diff --git a/components/weather-chart.tsx b/components/weather-chart.tsx new file mode 100644 index 0000000..b1ce66a --- /dev/null +++ b/components/weather-chart.tsx @@ -0,0 +1,118 @@ +import React, { useMemo } from 'react'; +import { Line, LineChart, CartesianGrid, XAxis, YAxis, ResponsiveContainer } from "recharts"; +import { Card, CardHeader, CardContent, CardTitle, CardDescription, CardFooter } from "@/components/ui/card"; +import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"; + +interface WeatherDataPoint { + date: string; + minTemp: number; + maxTemp: number; +} + +interface WeatherChartProps { + result: any; +} + +const WeatherChart: React.FC = React.memo(({ result }) => { + const { chartData, minTemp, maxTemp } = useMemo(() => { + const weatherData: WeatherDataPoint[] = result.list.map((item: any) => ({ + date: new Date(item.dt * 1000).toLocaleDateString(), + minTemp: Number((item.main.temp_min - 273.15).toFixed(1)), + maxTemp: Number((item.main.temp_max - 273.15).toFixed(1)), + })); + + const groupedData: { [key: string]: WeatherDataPoint } = weatherData.reduce((acc, curr) => { + if (!acc[curr.date]) { + acc[curr.date] = { ...curr }; + } else { + acc[curr.date].minTemp = Math.min(acc[curr.date].minTemp, curr.minTemp); + acc[curr.date].maxTemp = Math.max(acc[curr.date].maxTemp, curr.maxTemp); + } + return acc; + }, {} as { [key: string]: WeatherDataPoint }); + + const chartData = Object.values(groupedData); + + const minTemp = Math.min(...chartData.map(d => d.minTemp)); + const maxTemp = Math.max(...chartData.map(d => d.maxTemp)); + + return { chartData, minTemp, maxTemp }; + }, [result]); + + const chartConfig: ChartConfig = useMemo(() => ({ + minTemp: { + label: "Min Temp.", + color: "hsl(var(--chart-1))", + }, + maxTemp: { + label: "Max Temp.", + color: "hsl(var(--chart-2))", + }, + }), []); + + return ( + + + Weather Forecast for {result.city.name} + + Showing min and max temperatures for the next 5 days + + + + + + + + new Date(value).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })} + stroke="#9CA3AF" + /> + `${value}°C`} + stroke="#9CA3AF" + /> + } /> + + + + + + + +
    +
    +
    + {result.city.name}, {result.city.country} +
    +
    + Next 5 days forecast +
    +
    +
    +
    +
    + ); +}); + +WeatherChart.displayName = 'WeatherChart'; + +export default WeatherChart; \ No newline at end of file diff --git a/package.json b/package.json index fcb2457..2091a3d 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,11 @@ "lint": "next lint" }, "dependencies": { + "@ai-sdk/anthropic": "^0.0.51", "@ai-sdk/azure": "^0.0.31", "@ai-sdk/cohere": "latest", - "@ai-sdk/google": "^0.0.46", + "@ai-sdk/google": "^0.0.52", + "@ai-sdk/groq": "^0.0.1", "@ai-sdk/mistral": "^0.0.41", "@ai-sdk/openai": "^0.0.58", "@e2b/code-interpreter": "^0.0.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fc11ea..f4047d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@ai-sdk/anthropic': + specifier: ^0.0.51 + version: 0.0.51(zod@3.23.8) '@ai-sdk/azure': specifier: ^0.0.31 version: 0.0.31(zod@3.23.8) @@ -12,8 +15,11 @@ dependencies: specifier: latest version: 0.0.25(zod@3.23.8) '@ai-sdk/google': - specifier: ^0.0.46 - version: 0.0.46(zod@3.23.8) + specifier: ^0.0.52 + version: 0.0.52(zod@3.23.8) + '@ai-sdk/groq': + specifier: ^0.0.1 + version: 0.0.1(zod@3.23.8) '@ai-sdk/mistral': specifier: ^0.0.41 version: 0.0.41(zod@3.23.8) @@ -91,7 +97,7 @@ dependencies: version: 1.4.2 ai: specifier: latest - version: 3.4.9(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8) + version: 3.4.18(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8) anthropic-vertex-ai: specifier: ^1.0.0 version: 1.0.0(zod@3.23.8) @@ -226,6 +232,17 @@ devDependencies: packages: + /@ai-sdk/anthropic@0.0.51(zod@3.23.8): + resolution: {integrity: sha512-XPLBvdwdMlNAvGMyfsDgrCDXN2Wz7M+wfCJthqiwdiKHmq2jDLGdt0ZCAozgxxW28HVzMfJlFjuyECiA5Le3YA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + dependencies: + '@ai-sdk/provider': 0.0.24 + '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) + zod: 3.23.8 + dev: false + /@ai-sdk/azure@0.0.31(zod@3.23.8): resolution: {integrity: sha512-LTiv890qHcw3w87l+OOuYqW1HM9+7olS5mpSOriRY2uZxJWr3MGz8MYqJu2jGNajNKi4j64GsaOuNK69k8KXjw==} engines: {node: '>=18'} @@ -249,18 +266,29 @@ packages: zod: 3.23.8 dev: false - /@ai-sdk/google@0.0.46(zod@3.23.8): - resolution: {integrity: sha512-rsc3Wh54EfSt3l/7IqPdTeuxA7xvFk2p8/HxxyoHfcwvQYmQ/bpgxmadId862sVsK79L8k3iRxvVwGVkkaEeaA==} + /@ai-sdk/google@0.0.52(zod@3.23.8): + resolution: {integrity: sha512-bfsA/1Ae0SQ6NfLwWKs5SU4MBwlzJjVhK6bTVBicYFjUxg9liK/W76P1Tq/qK9OlrODACz3i1STOIWsFPpIOuQ==} 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.24 + '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) json-schema: 0.4.0 zod: 3.23.8 dev: false + /@ai-sdk/groq@0.0.1(zod@3.23.8): + resolution: {integrity: sha512-M8XHUovs2UqOx6xlhABXXCGlzbgeErSyIwvH1LQeDl3Z2CbSSgvttc0k6irm4J7ViuULE5XcIDQurXijIePWqQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + dependencies: + '@ai-sdk/provider': 0.0.24 + '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) + zod: 3.23.8 + dev: false + /@ai-sdk/mistral@0.0.41(zod@3.23.8): resolution: {integrity: sha512-UTVtdC61AF4KQWnM3VAoo6/gi7G1frL3qVlKyW5toiRAUjCdeqLJUF2ho2iO8yqf+qIT6j57jWT3o6pqREy3Wg==} engines: {node: '>=18'} @@ -402,8 +430,8 @@ packages: json-schema: 0.4.0 dev: false - /@ai-sdk/react@0.0.62(react@18.3.1)(zod@3.23.8): - resolution: {integrity: sha512-1asDpxgmeHWL0/EZPCLENxfOHT+0jce0z/zasRhascodm2S6f6/KZn5doLG9jdmarcb+GjMjFmmwyOVXz3W1xg==} + /@ai-sdk/react@0.0.64(react@18.3.1)(zod@3.23.8): + resolution: {integrity: sha512-4LN2vleyA6rYHZ4Rk9CdxnJgaVkNPJDD4Wx1brUhc5RvUxj3TODcm2UwGOR/mxv4pcydtZGELfQQs/i/tkAUCw==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 @@ -421,8 +449,8 @@ packages: zod: 3.23.8 dev: false - /@ai-sdk/solid@0.0.49(zod@3.23.8): - resolution: {integrity: sha512-KnfWTt640cS1hM2fFIba8KHSPLpOIWXtEm28pNCHTvqasVKlh2y/zMQANTwE18pF2nuXL9P9F5/dKWaPsaEzQw==} + /@ai-sdk/solid@0.0.50(zod@3.23.8): + resolution: {integrity: sha512-JF+KKOgGAgcROgae6FU+hAtxMRhR896SzwI3H1h5hFOZrjqYeYzemJoKzA5MR5IBnPSK4FzEjunc8G5L67TyzQ==} engines: {node: '>=18'} peerDependencies: solid-js: ^1.7.7 @@ -436,8 +464,8 @@ packages: - zod dev: false - /@ai-sdk/svelte@0.0.51(svelte@4.2.19)(zod@3.23.8): - resolution: {integrity: sha512-aIZJaIds+KpCt19yUDCRDWebzF/17GCY7gN9KkcA2QM6IKRO5UmMcqEYja0ZmwFQPm1kBZkF2njhr8VXis2mAw==} + /@ai-sdk/svelte@0.0.52(svelte@4.2.19)(zod@3.23.8): + resolution: {integrity: sha512-ZGd81ruVuqpOh1Suma+HwBMBywcOV0IUzi96Q3knIoZIz99sVwebSKH8ExMofXm49bQdCTRa73Wn8sTs6QDIYg==} engines: {node: '>=18'} peerDependencies: svelte: ^3.0.0 || ^4.0.0 @@ -470,8 +498,8 @@ packages: zod-to-json-schema: 3.23.2(zod@3.23.8) dev: false - /@ai-sdk/vue@0.0.54(vue@3.5.11)(zod@3.23.8): - resolution: {integrity: sha512-Ltu6gbuii8Qlp3gg7zdwdnHdS4M8nqKDij2VVO1223VOtIFwORFJzKqpfx44U11FW8z2TPVBYN+FjkyVIcN2hg==} + /@ai-sdk/vue@0.0.55(vue@3.5.11)(zod@3.23.8): + resolution: {integrity: sha512-NZ89CeRPO3D9GjI7GmK3vC+YXjsaWi3iCIvxlGqfQYt0JFKcjgM6dfeq8Nkk+qWI9OoxoOhV/yQdqWQKPv3RRg==} engines: {node: '>=18'} peerDependencies: vue: ^3.3.4 @@ -2021,8 +2049,8 @@ packages: humanize-ms: 1.2.1 dev: false - /ai@3.4.9(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8): - resolution: {integrity: sha512-wmVzpIHNGjCEjIJ/3945a/DIkz+gwObjC767ZRgO8AmtIZMO5KqvqNr7n2KF+gQrCPCMC8fM1ICQFXSvBZnBlA==} + /ai@3.4.18(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8): + resolution: {integrity: sha512-dc6rSBDgaRMX4VgTBsUZwEN5tBWMpJd+MJxB05E2cL4ft9mOmQEZNS6yeu4Ci5rUDj4ZhnmvANHrP7td8Ko9Og==} engines: {node: '>=18'} peerDependencies: openai: ^4.42.0 @@ -2044,11 +2072,11 @@ packages: dependencies: '@ai-sdk/provider': 0.0.24 '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) - '@ai-sdk/react': 0.0.62(react@18.3.1)(zod@3.23.8) - '@ai-sdk/solid': 0.0.49(zod@3.23.8) - '@ai-sdk/svelte': 0.0.51(svelte@4.2.19)(zod@3.23.8) + '@ai-sdk/react': 0.0.64(react@18.3.1)(zod@3.23.8) + '@ai-sdk/solid': 0.0.50(zod@3.23.8) + '@ai-sdk/svelte': 0.0.52(svelte@4.2.19)(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.46(zod@3.23.8) - '@ai-sdk/vue': 0.0.54(vue@3.5.11)(zod@3.23.8) + '@ai-sdk/vue': 0.0.55(vue@3.5.11)(zod@3.23.8) '@opentelemetry/api': 1.9.0 eventsource-parser: 1.1.2 json-schema: 0.4.0