11const axios = require ( 'axios' ) ;
22const { logger } = require ( '@librechat/data-schemas' ) ;
33const { tool } = require ( '@librechat/agents/langchain/tools' ) ;
4- const { generateShortLivedToken, logAxiosError } = require ( '@librechat/api' ) ;
5- const { Tools, EToolResources } = require ( 'librechat-data-provider' ) ;
4+ const {
5+ logAxiosError,
6+ selectFileCitationSources,
7+ generateShortLivedToken,
8+ } = require ( '@librechat/api' ) ;
9+ const { Tools, EModelEndpoint, EToolResources } = require ( 'librechat-data-provider' ) ;
610const { filterFilesByAgentAccess } = require ( '~/server/services/Files/permissions' ) ;
711const { getFiles } = require ( '~/models' ) ;
812
@@ -82,13 +86,20 @@ const primeFiles = async (options) => {
8286/**
8387 *
8488 * @param {Object } options
89+ * @param {AppConfig } [options.appConfig]
8590 * @param {string } options.userId
8691 * @param {Array<{ file_id: string; filename: string; fromAgent?: boolean }> } options.files
8792 * @param {string } [options.entity_id]
8893 * @param {boolean } [options.fileCitations=false] - Whether to include citation instructions
8994 * @returns
9095 */
91- const createFileSearchTool = async ( { userId, files, entity_id, fileCitations = false } ) => {
96+ const createFileSearchTool = async ( {
97+ userId,
98+ files,
99+ entity_id,
100+ fileCitations = false ,
101+ appConfig,
102+ } ) => {
92103 return tool (
93104 async ( { query } ) => {
94105 if ( files . length === 0 ) {
@@ -132,6 +143,7 @@ const createFileSearchTool = async ({ userId, files, entity_id, fileCitations =
132143 'Content-Type' : 'application/json' ,
133144 } ,
134145 } )
146+ . then ( ( result ) => ( { data : result . data , file_id : file . file_id } ) )
135147 . catch ( ( error ) => {
136148 logAxiosError ( {
137149 message : 'Error encountered in `file_search` while querying file' ,
@@ -149,12 +161,12 @@ const createFileSearchTool = async ({ userId, files, entity_id, fileCitations =
149161 }
150162
151163 const formattedResults = validResults
152- . flatMap ( ( result , fileIndex ) =>
164+ . flatMap ( ( result ) =>
153165 result . data . map ( ( [ docInfo , distance ] ) => ( {
154166 filename : docInfo . metadata . source . split ( '/' ) . pop ( ) ,
155167 content : docInfo . page_content ,
156168 distance,
157- file_id : files [ fileIndex ] ? .file_id ,
169+ file_id : result . file_id ,
158170 page : docInfo . metadata . page || null ,
159171 } ) ) ,
160172 )
@@ -168,15 +180,6 @@ const createFileSearchTool = async ({ userId, files, entity_id, fileCitations =
168180 ] ;
169181 }
170182
171- const formattedString = formattedResults
172- . map (
173- ( result , index ) =>
174- `File: ${ result . filename } ${
175- fileCitations ? `\nAnchor: \\ue202turn0file${ index } (${ result . filename } )` : ''
176- } \nRelevance: ${ ( 1.0 - result . distance ) . toFixed ( 4 ) } \nContent: ${ result . content } \n`,
177- )
178- . join ( '\n---\n' ) ;
179-
180183 const sources = formattedResults . map ( ( result ) => ( {
181184 type : 'file' ,
182185 fileId : result . file_id ,
@@ -187,6 +190,21 @@ const createFileSearchTool = async ({ userId, files, entity_id, fileCitations =
187190 pageRelevance : result . page ? { [ result . page ] : 1.0 - result . distance } : { } ,
188191 } ) ) ;
189192
193+ const citationConfig = appConfig ?. endpoints ?. [ EModelEndpoint . agents ] ;
194+ const citationSources = fileCitations
195+ ? selectFileCitationSources ( sources , citationConfig )
196+ : [ ] ;
197+ const formattedString = formattedResults
198+ . map ( ( result , index ) => {
199+ const citationIndex = citationSources . indexOf ( sources [ index ] ) ;
200+ return `File: ${ result . filename } ${
201+ citationIndex >= 0
202+ ? `\nAnchor: \\ue202turn0file${ citationIndex } (${ result . filename } )`
203+ : ''
204+ } \nRelevance: ${ ( 1.0 - result . distance ) . toFixed ( 4 ) } \nContent: ${ result . content } \n`;
205+ } )
206+ . join ( '\n---\n' ) ;
207+
190208 return [ formattedString , { [ Tools . file_search ] : { sources, fileCitations } } ] ;
191209 } ,
192210 {
0 commit comments