chore: remove pdf attachement

This commit is contained in:
Faisal Amir 2025-08-14 15:01:30 +07:00
parent ec9925ed5a
commit f70449fd98
5 changed files with 11 additions and 99 deletions

View File

@ -1,7 +1,7 @@
'use client'
import TextareaAutosize from 'react-textarea-autosize'
import { cn, toGigabytes } from '@/lib/utils'
import { cn } from '@/lib/utils'
import { usePrompt } from '@/hooks/usePrompt'
import { useThreads } from '@/hooks/useThreads'
import { useCallback, useEffect, useRef, useState } from 'react'
@ -191,8 +191,6 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
return 'image/jpeg'
case 'png':
return 'image/png'
case 'pdf':
return 'application/pdf'
default:
return ''
}
@ -226,21 +224,16 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
const detectedType = file.type || getFileTypeFromExtension(file.name)
const actualType = getFileTypeFromExtension(file.name) || detectedType
// Check file type - exclude PDF for local models (llamacpp)
// Check file type - images only
const allowedTypes = [
'image/jpg',
'image/jpeg',
'image/png',
...(model?.provider !== 'llamacpp' ? ['application/pdf'] : []),
]
if (!allowedTypes.includes(actualType)) {
const supportedFormats =
model?.provider === 'llamacpp'
? 'JPEG, JPG, and PNG'
: 'JPEG, JPG, PNG, and PDF'
setMessage(
`File attachments not supported currently. Only ${supportedFormats} files are allowed.`
`File attachments not supported currently. Only JPEG, JPG, and PNG files are allowed.`
)
// Reset file input to allow re-uploading
if (fileInputRef.current) {
@ -389,25 +382,6 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
alt={`${file.name} - ${index}`}
/>
)}
{file.type === 'application/pdf' && (
<div className="bg-main-view-fg/4 h-full rounded-lg p-2 max-w-[400px] pr-4">
<div className="flex gap-2 items-center justify-center h-full">
<div className="size-10 rounded-md bg-main-view shrink-0 flex items-center justify-center">
<span className="uppercase font-bold">
{file.name.split('.').pop()}
</span>
</div>
<div className="truncate">
<h6 className="truncate mb-0.5 text-main-view-fg/80">
{file.name}
</h6>
<p className="text-xs text-main-view-fg/70">
{toGigabytes(file.size)}
</p>
</div>
</div>
</div>
)}
<div
className="absolute -top-1 -right-2.5 bg-destructive size-5 flex rounded-full items-center justify-center cursor-pointer"
onClick={() => handleRemoveFile(index)}

View File

@ -224,11 +224,7 @@ export const ThreadContent = memo(
toSendMessage.content?.find((c) => c.type === 'text')?.text?.value ||
''
const attachments = toSendMessage.content
?.filter(
(c) =>
(c.type === 'image_url' && c.image_url?.url) ||
((c as any).type === 'file' && (c as any).file?.data)
)
?.filter((c) => (c.type === 'image_url' && c.image_url?.url) || false)
.map((c) => {
if (c.type === 'image_url' && c.image_url?.url) {
const url = c.image_url.url
@ -242,15 +238,6 @@ export const ThreadContent = memo(
base64: base64,
dataUrl: url,
}
} else if ((c as any).type === 'file' && (c as any).file?.data) {
const fileContent = (c as any).file
return {
name: fileContent.filename || 'file',
type: fileContent.media_type,
size: 0, // We don't have the original size
base64: fileContent.data,
dataUrl: `data:${fileContent.media_type};base64,${fileContent.data}`,
}
}
return null
})
@ -307,17 +294,14 @@ export const ThreadContent = memo(
<div className="w-full">
{/* Render attachments above the message bubble */}
{item.content?.some(
(c) =>
(c.type === 'image_url' && c.image_url?.url) ||
((c as any).type === 'file' && (c as any).file?.data)
(c) => (c.type === 'image_url' && c.image_url?.url) || false
) && (
<div className="flex justify-end w-full mb-2">
<div className="flex flex-wrap gap-2 max-w-[80%] justify-end">
{item.content
?.filter(
(c) =>
(c.type === 'image_url' && c.image_url?.url) ||
((c as any).type === 'file' && (c as any).file?.data)
(c.type === 'image_url' && c.image_url?.url) || false
)
.map((contentPart, index) => {
// Handle images
@ -335,27 +319,6 @@ export const ThreadContent = memo(
</div>
)
}
// Handle PDF files
else if (
(contentPart as any).type === 'file' &&
(contentPart as any).file?.media_type ===
'application/pdf'
) {
const fileContent = (contentPart as any).file
return (
<div key={index} className="relative">
<div className="w-40 h-40 bg-main-view-fg/5 border border-main-view-fg/10 rounded-md flex flex-col items-center justify-center p-4">
<div className="text-2xl mb-2">📄</div>
<div className="text-xs text-center text-main-view-fg/70 truncate w-full">
{fileContent.filename || 'PDF Document'}
</div>
<div className="text-xs text-main-view-fg/50 mt-1">
PDF
</div>
</div>
</div>
)
}
return null
})}
</div>

View File

@ -231,7 +231,7 @@ describe('ChatInput', () => {
const sendButton = document.querySelector('[data-test-id="send-message-button"]')
await user.click(sendButton)
expect(mockSendMessage).toHaveBeenCalledWith('Hello world')
expect(mockSendMessage).toHaveBeenCalledWith('Hello world', true, undefined)
})
it('sends message when Enter key is pressed', async () => {
@ -248,7 +248,7 @@ describe('ChatInput', () => {
const textarea = screen.getByRole('textbox')
await user.type(textarea, '{Enter}')
expect(mockSendMessage).toHaveBeenCalledWith('Hello world')
expect(mockSendMessage).toHaveBeenCalledWith('Hello world', true, undefined)
})
it('does not send message when Shift+Enter is pressed', async () => {

View File

@ -81,17 +81,6 @@ export const newUserThreadContent = (
detail: 'auto',
},
} as any)
} else if (attachment.type === 'application/pdf') {
contentParts.push({
type: 'file' as any,
file: {
filename: attachment.name,
file_data: `data:${attachment.type};base64,${attachment.base64}`,
// Keep original data for local display purposes
data: attachment.base64,
media_type: attachment.type,
},
} as any)
}
})
}

View File

@ -32,6 +32,7 @@ export class CompletionMessagesBuilder {
// For user messages, handle multimodal content
if (msg.content.length > 1) {
// Multiple content parts (text + images + files)
const content = msg.content.map((contentPart) => {
if (contentPart.type === 'text') {
return {
@ -46,16 +47,9 @@ export class CompletionMessagesBuilder {
detail: contentPart.image_url?.detail || 'auto',
},
}
} else if ((contentPart as any).type === 'file') {
return {
type: 'file',
file: {
filename: (contentPart as any).file?.filename || 'document.pdf',
file_data: (contentPart as any).file?.file_data || (contentPart as any).file?.data ? `data:application/pdf;base64,${(contentPart as any).file.data}` : '',
},
}
} else {
return contentPart
}
return contentPart
})
return {
role: msg.role,
@ -112,14 +106,6 @@ export class CompletionMessagesBuilder {
detail: 'auto',
},
})
} else if (attachment.type === 'application/pdf') {
messageContent.push({
type: 'file',
file: {
filename: attachment.name,
file_data: `data:${attachment.type};base64,${attachment.base64}`,
},
})
}
})