Skip to content

Commit 4880614

Browse files
committed
Clean up attachments
1 parent f74dade commit 4880614

3 files changed

Lines changed: 27 additions & 78 deletions

File tree

apps/sim/providers/attachments.ts

Lines changed: 23 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {
22
getContentType,
3+
getExtensionFromMimeType,
34
getFileExtension,
45
getMimeTypeFromExtension,
6+
MIME_TYPE_MAPPING,
57
MODEL_SUPPORTED_IMAGE_MIME_TYPES,
68
} from '@/lib/uploads/utils/file-utils'
79
import type { UserFile } from '@/executor/types'
@@ -37,64 +39,15 @@ export interface PreparedProviderAttachment {
3739
const AGENT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024
3840
const PDF_MIME_TYPE = 'application/pdf'
3941

40-
const TEXT_DOCUMENT_MIME_TYPES = new Set([
41-
'text/plain',
42-
'text/markdown',
43-
'text/csv',
44-
'text/html',
45-
'text/xml',
46-
'text/javascript',
47-
'text/typescript',
48-
'text/x-python',
49-
'text/x-go',
50-
'text/x-rust',
51-
'text/x-java',
52-
'text/x-kotlin',
53-
'text/x-c',
54-
'text/x-c++',
55-
'text/x-csharp',
56-
'text/x-ruby',
57-
'text/x-php',
58-
'text/x-swift',
59-
'text/x-shellscript',
60-
'application/json',
61-
'application/xml',
62-
'application/x-yaml',
63-
])
42+
const DOCUMENT_MIME_TYPES = new Set(
43+
Object.entries(MIME_TYPE_MAPPING)
44+
.filter(([, contentType]) => contentType === 'document')
45+
.map(([mimeType]) => mimeType)
46+
)
6447

65-
const OPENAI_DOCUMENT_MIME_TYPES = new Set([
66-
PDF_MIME_TYPE,
67-
...TEXT_DOCUMENT_MIME_TYPES,
68-
'application/rtf',
69-
'application/msword',
70-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
71-
'application/vnd.ms-powerpoint',
72-
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
73-
'application/vnd.ms-excel',
74-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
75-
])
48+
const OPENAI_DOCUMENT_MIME_TYPES = new Set([...DOCUMENT_MIME_TYPES, 'application/x-yaml'])
7649

77-
const GEMINI_INLINE_MIME_TYPES = new Set([
78-
PDF_MIME_TYPE,
79-
...TEXT_DOCUMENT_MIME_TYPES,
80-
...MODEL_SUPPORTED_IMAGE_MIME_TYPES,
81-
'audio/mpeg',
82-
'audio/mp3',
83-
'audio/mp4',
84-
'audio/x-m4a',
85-
'audio/m4a',
86-
'audio/wav',
87-
'audio/wave',
88-
'audio/x-wav',
89-
'audio/webm',
90-
'audio/ogg',
91-
'audio/flac',
92-
'video/mp4',
93-
'video/mpeg',
94-
'video/quicktime',
95-
'video/x-quicktime',
96-
'video/webm',
97-
])
50+
const GEMINI_INLINE_MIME_TYPES = new Set([...Object.keys(MIME_TYPE_MAPPING), 'application/x-yaml'])
9851

9952
const BEDROCK_DOCUMENT_FORMATS = new Set([
10053
'pdf',
@@ -168,7 +121,12 @@ export function inferAttachmentMimeType(file: UserFile): string {
168121
}
169122

170123
function isTextDocumentMimeType(mimeType: string): boolean {
171-
return TEXT_DOCUMENT_MIME_TYPES.has(mimeType) || mimeType.startsWith('text/')
124+
return (
125+
mimeType.startsWith('text/') ||
126+
mimeType === 'application/json' ||
127+
mimeType === 'application/xml' ||
128+
mimeType === 'application/x-yaml'
129+
)
172130
}
173131

174132
function isImageMimeType(mimeType: string): boolean {
@@ -179,6 +137,12 @@ function isOpenAIDocumentMimeType(mimeType: string): boolean {
179137
return OPENAI_DOCUMENT_MIME_TYPES.has(mimeType) || isTextDocumentMimeType(mimeType)
180138
}
181139

140+
function getAttachmentContentType(
141+
mimeType: string
142+
): PreparedProviderAttachment['contentType'] | null {
143+
return getContentType(mimeType) || (isTextDocumentMimeType(mimeType) ? 'document' : null)
144+
}
145+
182146
function sniffImageMimeType(base64: string): string {
183147
let bytes: Buffer
184148
try {
@@ -218,23 +182,8 @@ function sniffImageMimeType(base64: string): string {
218182
}
219183

220184
function getAttachmentExtension(file: UserFile, mimeType: string): string {
221-
if (mimeType === 'image/jpeg' || mimeType === 'image/jpg') return 'jpeg'
222-
if (mimeType === 'image/png') return 'png'
223-
if (mimeType === 'image/gif') return 'gif'
224-
if (mimeType === 'image/webp') return 'webp'
225-
if (mimeType === 'video/mp4') return 'mp4'
226-
if (mimeType === 'video/quicktime' || mimeType === 'video/x-quicktime') return 'mov'
227-
if (mimeType === 'video/webm') return 'webm'
228-
229-
const extension = getFileExtension(file.name)
230-
if (extension) return extension
231-
232-
if (mimeType === 'application/pdf') return 'pdf'
233185
if (mimeType === 'text/markdown') return 'md'
234-
if (mimeType === 'text/plain') return 'txt'
235-
if (mimeType === 'text/csv') return 'csv'
236-
if (mimeType === 'text/html') return 'html'
237-
return ''
186+
return getExtensionFromMimeType(mimeType) || getFileExtension(file.name)
238187
}
239188

240189
function normalizeProviderMimeType(mimeType: string, provider: AttachmentProvider): string {
@@ -315,7 +264,7 @@ export function prepareProviderAttachments(
315264

316265
return files.map((file) => {
317266
const declaredMimeType = inferAttachmentMimeType(file)
318-
const contentType = getContentType(declaredMimeType)
267+
const contentType = getAttachmentContentType(declaredMimeType)
319268

320269
if (!contentType) {
321270
throw new Error(

apps/sim/providers/google/utils.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ describe('convertToGeminiFormat', () => {
126126
url: '/api/files/serve/workspace%2Fws-1%2Fexample.png?context=workspace',
127127
size: 128,
128128
type: 'image/png',
129-
base64: 'aW1hZ2U=',
129+
base64: 'iVBORw0KGgo=',
130130
},
131131
],
132132
},
@@ -142,7 +142,7 @@ describe('convertToGeminiFormat', () => {
142142
{
143143
inlineData: {
144144
mimeType: 'image/png',
145-
data: 'aW1hZ2U=',
145+
data: 'iVBORw0KGgo=',
146146
},
147147
},
148148
],

apps/sim/providers/openai/utils.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('buildResponsesInputFromMessages', () => {
1818
url: '/api/files/serve/workspace%2Fws-1%2Fexample.png?context=workspace',
1919
size: 128,
2020
type: 'image/png',
21-
base64: 'aW1hZ2U=',
21+
base64: 'iVBORw0KGgo=',
2222
},
2323
],
2424
},
@@ -31,7 +31,7 @@ describe('buildResponsesInputFromMessages', () => {
3131
{ type: 'input_text', text: 'Analyze this image' },
3232
{
3333
type: 'input_image',
34-
image_url: 'data:image/png;base64,aW1hZ2U=',
34+
image_url: 'data:image/png;base64,iVBORw0KGgo=',
3535
},
3636
],
3737
},

0 commit comments

Comments
 (0)