File size: 4,734 Bytes
31dd200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**

 * File validation utilities based on model modalities

 * Ensures only compatible file types are processed based on model capabilities

 */

import { getFileTypeCategory } from '$lib/utils';
import { FileTypeCategory } from '$lib/enums';
import type { ModalityCapabilities } from '$lib/types';

/**

 * Check if a file type is supported by the given modalities

 * @param filename - The filename to check

 * @param mimeType - The MIME type of the file

 * @param capabilities - The modality capabilities to check against

 * @returns true if the file type is supported

 */
export function isFileTypeSupportedByModel(

	filename: string,

	mimeType: string | undefined,

	capabilities: ModalityCapabilities

): boolean {
	const category = mimeType ? getFileTypeCategory(mimeType) : null;

	// If we can't determine the category from MIME type, fall back to general support check
	if (!category) {
		// For unknown types, only allow if they might be text files
		// This is a conservative approach for edge cases
		return true; // Let the existing isFileTypeSupported handle this
	}

	switch (category) {
		case FileTypeCategory.TEXT:
			// Text files are always supported
			return true;

		case FileTypeCategory.PDF:
			// PDFs are always supported (will be processed as text for non-vision models)
			return true;

		case FileTypeCategory.IMAGE:
			// Images require vision support
			return capabilities.hasVision;

		case FileTypeCategory.AUDIO:
			// Audio files require audio support
			return capabilities.hasAudio;

		default:
			// Unknown categories - be conservative and allow
			return true;
	}
}

/**

 * Filter files based on model modalities and return supported/unsupported lists

 * @param files - Array of files to filter

 * @param capabilities - The modality capabilities to check against

 * @returns Object with supportedFiles and unsupportedFiles arrays

 */
export function filterFilesByModalities(

	files: File[],

	capabilities: ModalityCapabilities

): {
	supportedFiles: File[];
	unsupportedFiles: File[];
	modalityReasons: Record<string, string>;
} {
	const supportedFiles: File[] = [];
	const unsupportedFiles: File[] = [];
	const modalityReasons: Record<string, string> = {};

	const { hasVision, hasAudio } = capabilities;

	for (const file of files) {
		const category = getFileTypeCategory(file.type);
		let isSupported = true;
		let reason = '';

		switch (category) {
			case FileTypeCategory.IMAGE:
				if (!hasVision) {
					isSupported = false;
					reason = 'Images require a vision-capable model';
				}
				break;

			case FileTypeCategory.AUDIO:
				if (!hasAudio) {
					isSupported = false;
					reason = 'Audio files require an audio-capable model';
				}
				break;

			case FileTypeCategory.TEXT:
			case FileTypeCategory.PDF:
				// Always supported
				break;

			default:
				// For unknown types, check if it's a generally supported file type
				// This handles edge cases and maintains backward compatibility
				break;
		}

		if (isSupported) {
			supportedFiles.push(file);
		} else {
			unsupportedFiles.push(file);
			modalityReasons[file.name] = reason;
		}
	}

	return { supportedFiles, unsupportedFiles, modalityReasons };
}

/**

 * Generate a user-friendly error message for unsupported files

 * @param unsupportedFiles - Array of unsupported files

 * @param modalityReasons - Reasons why files are unsupported

 * @param capabilities - The modality capabilities to check against

 * @returns Formatted error message

 */
export function generateModalityErrorMessage(

	unsupportedFiles: File[],

	modalityReasons: Record<string, string>,

	capabilities: ModalityCapabilities

): string {
	if (unsupportedFiles.length === 0) return '';

	const { hasVision, hasAudio } = capabilities;

	let message = '';

	if (unsupportedFiles.length === 1) {
		const file = unsupportedFiles[0];
		const reason = modalityReasons[file.name];
		message = `The file "${file.name}" cannot be uploaded: ${reason}.`;
	} else {
		const fileNames = unsupportedFiles.map((f) => f.name).join(', ');
		message = `The following files cannot be uploaded: ${fileNames}.`;
	}

	// Add helpful information about what is supported
	const supportedTypes: string[] = ['text files', 'PDFs'];
	if (hasVision) supportedTypes.push('images');
	if (hasAudio) supportedTypes.push('audio files');

	message += ` This model supports: ${supportedTypes.join(', ')}.`;

	return message;
}

/**

 * Generate file input accept string based on model modalities

 * @param capabilities - The modality capabilities to check against

 * @returns Accept string for HTML file input element

 */