import type { CoreAssistantMessage, CoreToolMessage, UIMessage } from 'ai' import { clsx, type ClassValue } from 'clsx' import { twMerge } from 'tailwind-merge' import { IDocument } from '@penx/model-type' 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 }