import type { CoreAssistantMessage, CoreToolMessage, UIMessage } from 'ai'; import { type ClassValue, clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; import type { Document } from '@/lib/db/schema'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } interface ApplicationError extends Error { info: string; status: number; } export const fetcher = async (url: string) => { const res = await fetch(url); if (!res.ok) { const error = new Error( 'An error occurred while fetching the data.', ) as ApplicationError; error.info = await res.json(); error.status = res.status; throw error; } return res.json(); }; export function getLocalStorage(key: string) { if (typeof window !== 'undefined') { return JSON.parse(localStorage.getItem(key) || '[]'); } return []; } export function generateUUID(): string { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0; const v = c === 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); } type ResponseMessageWithoutId = CoreToolMessage | CoreAssistantMessage; type ResponseMessage = ResponseMessageWithoutId & { id: string }; export function getMostRecentUserMessage(messages: Array) { const userMessages = messages.filter((message) => message.role === 'user'); return userMessages.at(-1); } export function getDocumentTimestampByIndex( documents: Array, index: number, ) { if (!documents) return new Date(); if (index > documents.length) return new Date(); return documents[index].createdAt; } export function getTrailingMessageId({ messages, }: { messages: Array; }): string | null { const trailingMessage = messages.at(-1); if (!trailingMessage) return null; return trailingMessage.id; }