diff --git a/next.config.mjs b/next.config.mjs index 83d1159..fc5e0f6 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,10 +1,10 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - experimental: { - serverActions: { - bodySizeLimit: '10mb', - }, - }, + experimental: { + serverActions: { + bodySizeLimit: "10mb", + }, + }, }; export default nextConfig; diff --git a/src/components/thread/index.tsx b/src/components/thread/index.tsx index 5fab5c2..b592946 100644 --- a/src/components/thread/index.tsx +++ b/src/components/thread/index.tsx @@ -40,6 +40,11 @@ import { import type { Base64ContentBlock } from "@/lib/pdf"; type MessageContentType = Message["content"]; +interface UploadedBlock { + id: string; + name: string; + block: Base64ContentBlock; +} function StickyToBottomContent(props: { content: ReactNode; @@ -106,12 +111,6 @@ function OpenGitHubRepo() { ); } -interface UploadedBlock { - id: string; - name: string; - block: Base64ContentBlock; -} - export function Thread() { const [threadId, setThreadId] = useQueryState("threadId"); const [chatHistoryOpen, setChatHistoryOpen] = useQueryState( @@ -192,7 +191,6 @@ export function Thread() { ...pdfUrlList.map((item) => item.block), ] as MessageContentType, }; - const toolMessages = ensureToolCallsHaveResponses(stream.messages); stream.submit( @@ -240,14 +238,13 @@ export function Thread() { }; reader.readAsDataURL(file); }); - }) + }), ); setImageUrlList([...imageUrlList, ...imageFiles]); } e.target.value = ""; }; - const handlePDFUpload = async (e: ChangeEvent) => { const files = e.target.files; if (files) { @@ -274,7 +271,7 @@ export function Thread() { }; reader.readAsDataURL(file); }); - }) + }), ); console.log(pdfFiles[0]); setPdfUrlList([...pdfUrlList, ...pdfFiles]); @@ -282,9 +279,6 @@ export function Thread() { e.target.value = ""; }; - - - const handleRegenerate = ( parentCheckpoint: Checkpoint | null | undefined, ) => { @@ -317,12 +311,17 @@ export function Thread() { if (!e.dataTransfer) return; const files = Array.from(e.dataTransfer.files); - const imageFiles = files.filter((file) => - file.type.startsWith("image/"), - ); + const imageFiles = files.filter((file) => file.type.startsWith("image/")); - if (files.some(file => !file.type.startsWith("image/") || file.type !== "application/pdf")) { - toast.error("You have uploaded invalid file type. Please upload an image or a PDF."); + if ( + files.some( + (file) => + !file.type.startsWith("image/") || file.type !== "application/pdf", + ) + ) { + toast.error( + "You have uploaded invalid file type. Please upload an image or a PDF.", + ); } /** @@ -354,7 +353,7 @@ export function Thread() { }; reader.readAsDataURL(file); }); - }) + }), ); setImageUrlList([...imageUrlList, ...imageFilesData]); } @@ -363,8 +362,10 @@ export function Thread() { * If there are any PDF files in the dropped files, this block previews the file name of each uploaded PDF * by rendering a list of file names above the input area, with a remove button for each. */ - if (files.some(file => file.type === "application/pdf")) { - const pdfFiles = files.filter(file => file.type === "application/pdf"); + if (files.some((file) => file.type === "application/pdf")) { + const pdfFiles = files.filter( + (file) => file.type === "application/pdf", + ); const pdfFilesData: UploadedBlock[] = await Promise.all( pdfFiles.map((file) => { return new Promise((resolve) => { @@ -373,7 +374,8 @@ export function Thread() { const result = reader.result as string; const base64 = result.split(",")[1]; const match = result.match(/^data:(.*);base64/); - const mimeType = match && match[1] ? match[1] : "application/pdf"; + const mimeType = + match && match[1] ? match[1] : "application/pdf"; resolve({ id: uuidv4(), name: file.name, @@ -388,7 +390,7 @@ export function Thread() { }; reader.readAsDataURL(file); }); - }) + }), ); setPdfUrlList([...pdfUrlList, ...pdfFilesData]); } @@ -418,7 +420,6 @@ export function Thread() { }; }); - return (
@@ -640,13 +641,22 @@ export function Thread() {
)} {pdfUrlList.length > 0 && ( -
+
{pdfUrlList.map((pdf) => ( -
- {pdf.name} +
+ + {pdf.name} + setPdfUrlList(pdfUrlList.filter((p) => p.id !== pdf.id))} + onClick={() => + setPdfUrlList( + pdfUrlList.filter((p) => p.id !== pdf.id), + ) + } />
))} diff --git a/src/lib/pdf.ts b/src/lib/pdf.ts index 81af354..15678e5 100644 --- a/src/lib/pdf.ts +++ b/src/lib/pdf.ts @@ -1,30 +1,28 @@ -"use server" -import { MessageContentText } from "@langchain/core/messages"; +"use server"; +import { MessageContentText } from "@langchain/core/messages"; import { WebPDFLoader } from "@langchain/community/document_loaders/web/pdf"; // import { Base64ContentBlock } from "@langchain/core/messages"; // switch local import with above import export interface Base64ContentBlock { - data: string; - metadata?: Record; - mime_type?: string; - source_type: "base64"; - type: "image" | "audio" | "file"; + data: string; + metadata?: Record; + mime_type?: string; + source_type: "base64"; + type: "image" | "audio" | "file"; } -export const extractPdfText = async (file: File): Promise => { - - const loader = new WebPDFLoader(file, { splitPages: false }); - const docs = await loader.load(); - return { - type: "text", - text: docs[0].pageContent, - }; +export const extractPdfText = async ( + file: File, +): Promise => { + const loader = new WebPDFLoader(file, { splitPages: false }); + const docs = await loader.load(); + return { + type: "text", + text: docs[0].pageContent, }; +}; - - const cleanBase64 = (base64String: string): string => { - return base64String.replace(/^data:.*?;base64,/, ""); - }; - - +const cleanBase64 = (base64String: string): string => { + return base64String.replace(/^data:.*?;base64,/, ""); +};