From cf3d48c0eefa595ca8f78b94fc6eb84dbe184a70 Mon Sep 17 00:00:00 2001
From: Waleed Latif
Date: Fri, 13 Jun 2025 11:13:09 -0700
Subject: [PATCH] fix(file-upload): upload presigned url to kb for file upload
instead of the whole file, circumvents 4.5MB serverless func limit
---
.../components/create-form/create-form.tsx | 98 ++++++++++++++-----
1 file changed, 73 insertions(+), 25 deletions(-)
diff --git a/apps/sim/app/w/knowledge/components/create-modal/components/create-form/create-form.tsx b/apps/sim/app/w/knowledge/components/create-modal/components/create-form/create-form.tsx
index 0cd1c9bd86d..211868f6dfd 100644
--- a/apps/sim/app/w/knowledge/components/create-modal/components/create-form/create-form.tsx
+++ b/apps/sim/app/w/knowledge/components/create-modal/components/create-form/create-form.tsx
@@ -17,7 +17,7 @@ import { useKnowledgeStore } from '@/stores/knowledge/store'
const logger = createLogger('CreateForm')
-const MAX_FILE_SIZE = 50 * 1024 * 1024 // 50MB
+const MAX_FILE_SIZE = 100 * 1024 * 1024 // 100MB
const ACCEPTED_FILE_TYPES = [
'application/pdf',
'application/msword',
@@ -107,7 +107,7 @@ export function CreateForm({ onClose, onKnowledgeBaseCreated }: CreateFormProps)
for (const file of Array.from(fileList)) {
// Check file size
if (file.size > MAX_FILE_SIZE) {
- setFileError(`File ${file.name} is too large. Maximum size is 50MB.`)
+ setFileError(`File ${file.name} is too large. Maximum size is 100MB per file.`)
hasError = true
continue
}
@@ -259,29 +259,77 @@ export function CreateForm({ onClose, onKnowledgeBaseCreated }: CreateFormProps)
const uploadedFiles: UploadedFile[] = []
for (const file of files) {
- const formData = new FormData()
- formData.append('file', file)
-
- const uploadResponse = await fetch('/api/files/upload', {
- method: 'POST',
- body: formData,
- })
+ try {
+ const presignedResponse = await fetch('/api/files/presigned', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ fileName: file.name,
+ contentType: file.type,
+ fileSize: file.size,
+ }),
+ })
- if (!uploadResponse.ok) {
- const errorData = await uploadResponse.json()
- throw new Error(`Failed to upload ${file.name}: ${errorData.error || 'Unknown error'}`)
+ const presignedData = await presignedResponse.json()
+
+ if (presignedResponse.ok && presignedData.directUploadSupported) {
+ const uploadResponse = await fetch(presignedData.presignedUrl, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': file.type,
+ },
+ body: file,
+ })
+
+ if (!uploadResponse.ok) {
+ throw new Error(
+ `Direct upload failed: ${uploadResponse.status} ${uploadResponse.statusText}`
+ )
+ }
+
+ uploadedFiles.push({
+ filename: file.name,
+ fileUrl: presignedData.fileInfo.path.startsWith('http')
+ ? presignedData.fileInfo.path
+ : `${window.location.origin}${presignedData.fileInfo.path}`,
+ fileSize: file.size,
+ mimeType: file.type,
+ fileHash: undefined,
+ })
+ } else {
+ const formData = new FormData()
+ formData.append('file', file)
+
+ const uploadResponse = await fetch('/api/files/upload', {
+ method: 'POST',
+ body: formData,
+ })
+
+ if (!uploadResponse.ok) {
+ const errorData = await uploadResponse.json()
+ throw new Error(
+ `Failed to upload ${file.name}: ${errorData.error || 'Unknown error'}`
+ )
+ }
+
+ const uploadResult = await uploadResponse.json()
+ uploadedFiles.push({
+ filename: file.name,
+ fileUrl: uploadResult.path.startsWith('http')
+ ? uploadResult.path
+ : `${window.location.origin}${uploadResult.path}`,
+ fileSize: file.size,
+ mimeType: file.type,
+ fileHash: undefined,
+ })
+ }
+ } catch (error) {
+ throw new Error(
+ `Failed to upload ${file.name}: ${error instanceof Error ? error.message : 'Unknown error'}`
+ )
}
-
- const uploadResult = await uploadResponse.json()
- uploadedFiles.push({
- filename: file.name,
- fileUrl: uploadResult.path.startsWith('http')
- ? uploadResult.path
- : `${window.location.origin}${uploadResult.path}`,
- fileSize: file.size,
- mimeType: file.type,
- fileHash: undefined,
- })
}
// Start async document processing
@@ -466,7 +514,7 @@ export function CreateForm({ onClose, onKnowledgeBaseCreated }: CreateFormProps)
{isDragging ? 'Drop files here!' : 'Drop files here or click to browse'}
- Supports PDF, DOC, DOCX, TXT, CSV, XLS, XLSX (max 50MB each)
+ Supports PDF, DOC, DOCX, TXT, CSV, XLS, XLSX (max 100MB each)
@@ -508,7 +556,7 @@ export function CreateForm({ onClose, onKnowledgeBaseCreated }: CreateFormProps)
: 'Drop more files or click to browse'}
- PDF, DOC, DOCX, TXT, CSV, XLS, XLSX (max 50MB each)
+ PDF, DOC, DOCX, TXT, CSV, XLS, XLSX (max 100MB each)