|
1 | 1 | const crypto = require('crypto'); |
2 | 2 | const fetch = require('node-fetch'); |
3 | 3 | const { logger } = require('@librechat/data-schemas'); |
4 | | -const { getBalanceConfig } = require('@librechat/api'); |
5 | 4 | const { |
6 | | - supportsBalanceCheck, |
7 | | - isAgentsEndpoint, |
8 | | - isParamEndpoint, |
9 | | - EModelEndpoint, |
| 5 | + getBalanceConfig, |
| 6 | + encodeAndFormatAudios, |
| 7 | + encodeAndFormatVideos, |
| 8 | + encodeAndFormatDocuments, |
| 9 | +} = require('@librechat/api'); |
| 10 | +const { |
| 11 | + Constants, |
| 12 | + ErrorTypes, |
10 | 13 | ContentTypes, |
11 | 14 | excludedKeys, |
12 | | - ErrorTypes, |
13 | | - Constants, |
| 15 | + EModelEndpoint, |
| 16 | + isParamEndpoint, |
| 17 | + isAgentsEndpoint, |
| 18 | + supportsBalanceCheck, |
14 | 19 | } = require('librechat-data-provider'); |
15 | 20 | const { getMessages, saveMessage, updateMessage, saveConvo, getConvo } = require('~/models'); |
| 21 | +const { getStrategyFunctions } = require('~/server/services/Files/strategies'); |
16 | 22 | const { checkBalance } = require('~/models/balanceMethods'); |
17 | 23 | const { truncateToolCallOutputs } = require('./prompts'); |
18 | 24 | const { getFiles } = require('~/models/File'); |
@@ -1198,8 +1204,99 @@ class BaseClient { |
1198 | 1204 | return await this.sendCompletion(payload, opts); |
1199 | 1205 | } |
1200 | 1206 |
|
| 1207 | + async addDocuments(message, attachments) { |
| 1208 | + const documentResult = await encodeAndFormatDocuments( |
| 1209 | + this.options.req, |
| 1210 | + attachments, |
| 1211 | + { |
| 1212 | + provider: this.options.agent?.provider, |
| 1213 | + useResponsesApi: this.options.agent?.model_parameters?.useResponsesApi, |
| 1214 | + }, |
| 1215 | + getStrategyFunctions, |
| 1216 | + ); |
| 1217 | + message.documents = |
| 1218 | + documentResult.documents && documentResult.documents.length |
| 1219 | + ? documentResult.documents |
| 1220 | + : undefined; |
| 1221 | + return documentResult.files; |
| 1222 | + } |
| 1223 | + |
| 1224 | + async addVideos(message, attachments) { |
| 1225 | + const videoResult = await encodeAndFormatVideos( |
| 1226 | + this.options.req, |
| 1227 | + attachments, |
| 1228 | + this.options.agent.provider, |
| 1229 | + getStrategyFunctions, |
| 1230 | + ); |
| 1231 | + message.videos = |
| 1232 | + videoResult.videos && videoResult.videos.length ? videoResult.videos : undefined; |
| 1233 | + return videoResult.files; |
| 1234 | + } |
| 1235 | + |
| 1236 | + async addAudios(message, attachments) { |
| 1237 | + const audioResult = await encodeAndFormatAudios( |
| 1238 | + this.options.req, |
| 1239 | + attachments, |
| 1240 | + this.options.agent.provider, |
| 1241 | + getStrategyFunctions, |
| 1242 | + ); |
| 1243 | + message.audios = |
| 1244 | + audioResult.audios && audioResult.audios.length ? audioResult.audios : undefined; |
| 1245 | + return audioResult.files; |
| 1246 | + } |
| 1247 | + |
| 1248 | + async processAttachments(message, attachments) { |
| 1249 | + const categorizedAttachments = { |
| 1250 | + images: [], |
| 1251 | + documents: [], |
| 1252 | + videos: [], |
| 1253 | + audios: [], |
| 1254 | + }; |
| 1255 | + |
| 1256 | + for (const file of attachments) { |
| 1257 | + if (file.type.startsWith('image/')) { |
| 1258 | + categorizedAttachments.images.push(file); |
| 1259 | + } else if (file.type === 'application/pdf') { |
| 1260 | + categorizedAttachments.documents.push(file); |
| 1261 | + } else if (file.type.startsWith('video/')) { |
| 1262 | + categorizedAttachments.videos.push(file); |
| 1263 | + } else if (file.type.startsWith('audio/')) { |
| 1264 | + categorizedAttachments.audios.push(file); |
| 1265 | + } |
| 1266 | + } |
| 1267 | + |
| 1268 | + const [imageFiles, documentFiles, videoFiles, audioFiles] = await Promise.all([ |
| 1269 | + categorizedAttachments.images.length > 0 |
| 1270 | + ? this.addImageURLs(message, categorizedAttachments.images) |
| 1271 | + : Promise.resolve([]), |
| 1272 | + categorizedAttachments.documents.length > 0 |
| 1273 | + ? this.addDocuments(message, categorizedAttachments.documents) |
| 1274 | + : Promise.resolve([]), |
| 1275 | + categorizedAttachments.videos.length > 0 |
| 1276 | + ? this.addVideos(message, categorizedAttachments.videos) |
| 1277 | + : Promise.resolve([]), |
| 1278 | + categorizedAttachments.audios.length > 0 |
| 1279 | + ? this.addAudios(message, categorizedAttachments.audios) |
| 1280 | + : Promise.resolve([]), |
| 1281 | + ]); |
| 1282 | + |
| 1283 | + const allFiles = [...imageFiles, ...documentFiles, ...videoFiles, ...audioFiles]; |
| 1284 | + const seenFileIds = new Set(); |
| 1285 | + const uniqueFiles = []; |
| 1286 | + |
| 1287 | + for (const file of allFiles) { |
| 1288 | + if (file.file_id && !seenFileIds.has(file.file_id)) { |
| 1289 | + seenFileIds.add(file.file_id); |
| 1290 | + uniqueFiles.push(file); |
| 1291 | + } else if (!file.file_id) { |
| 1292 | + uniqueFiles.push(file); |
| 1293 | + } |
| 1294 | + } |
| 1295 | + |
| 1296 | + return uniqueFiles; |
| 1297 | + } |
| 1298 | + |
1201 | 1299 | /** |
1202 | | - * |
1203 | 1300 | * @param {TMessage[]} _messages |
1204 | 1301 | * @returns {Promise<TMessage[]>} |
1205 | 1302 | */ |
@@ -1248,7 +1345,7 @@ class BaseClient { |
1248 | 1345 | {}, |
1249 | 1346 | ); |
1250 | 1347 |
|
1251 | | - await this.addImageURLs(message, files, this.visionMode); |
| 1348 | + await this.processAttachments(message, files); |
1252 | 1349 |
|
1253 | 1350 | this.message_file_map[message.messageId] = files; |
1254 | 1351 | return message; |
|
0 commit comments