@@ -94,43 +94,72 @@ class OpenRouterService {
9494 { role : 'user' , content : userContent }
9595 ] ;
9696
97- const requestBody = {
98- model : this . model ,
99- messages : messages ,
100- response_format : openRouterMCQSchema ,
101- temperature : config . openrouter . temperature ,
102- max_tokens : config . openrouter . maxTokens ,
103- top_p : 0.9 ,
104- plugins : [ { id : 'file-parser' , pdf : { engine : this . pdfEngine } } ] ,
105- tools : useSearch ? [ this . searchTool ] : undefined ,
106- tool_choice : useSearch ? "auto" : "none" ,
107- } ;
97+ let responseMessage ;
10898
109- const initialResponse = await this . _makeChatAPIRequest ( requestBody ) ;
110-
111- let responseMessage = initialResponse . choices [ 0 ] . message ;
112- messages . push ( responseMessage ) ;
113-
114- if ( useSearch && responseMessage . tool_calls ) {
115- logger . info ( 'Model requested a tool call for search.' ) ;
116- for ( const toolCall of responseMessage . tool_calls ) {
117- const functionName = toolCall . function . name ;
118- if ( this . toolMapping [ functionName ] ) {
119- const functionArgs = JSON . parse ( toolCall . function . arguments ) ;
120- const functionResponse = await this . toolMapping [ functionName ] ( functionArgs ) ;
121- messages . push ( {
122- tool_call_id : toolCall . id ,
123- role : "tool" ,
124- name : functionName ,
125- content : functionResponse ,
126- } ) ;
99+ if ( useSearch ) {
100+ // Step 1: Make a request with tools enabled, but no response_format
101+ const toolRequest = {
102+ model : this . model ,
103+ messages : messages ,
104+ temperature : config . openrouter . temperature ,
105+ max_tokens : config . openrouter . maxTokens ,
106+ top_p : 0.9 ,
107+ plugins : [ { id : 'file-parser' , pdf : { engine : this . pdfEngine } } ] ,
108+ tools : [ this . searchTool ] ,
109+ tool_choice : "auto" ,
110+ } ;
111+
112+ const initialResponse = await this . _makeChatAPIRequest ( toolRequest ) ;
113+ let intermediateMessage = initialResponse . choices [ 0 ] . message ;
114+ messages . push ( intermediateMessage ) ;
115+
116+ // Step 2: Handle tool calls if any
117+ if ( intermediateMessage . tool_calls ) {
118+ logger . info ( 'Model requested a tool call for search.' ) ;
119+ for ( const toolCall of intermediateMessage . tool_calls ) {
120+ const functionName = toolCall . function . name ;
121+ if ( this . toolMapping [ functionName ] ) {
122+ const functionArgs = JSON . parse ( toolCall . function . arguments ) ;
123+ const functionResponse = await this . toolMapping [ functionName ] ( functionArgs ) ;
124+ messages . push ( {
125+ tool_call_id : toolCall . id ,
126+ role : "tool" ,
127+ name : functionName ,
128+ content : functionResponse ,
129+ } ) ;
130+ }
127131 }
132+ } else {
133+ logger . info ( 'Model did not request a tool call. Proceeding to format response.' ) ;
128134 }
129135
130- logger . info ( 'Sending tool response back to the model to generate final quiz.' ) ;
131- const finalRequestBody = { ...requestBody , messages : messages , tools : undefined , tool_choice : undefined } ;
132- const finalResponse = await this . _makeChatAPIRequest ( finalRequestBody ) ;
136+ // Step 3: Make the final request to get a structured JSON response
137+ const finalRequest = {
138+ model : this . model ,
139+ messages : messages ,
140+ response_format : openRouterMCQSchema ,
141+ temperature : config . openrouter . temperature ,
142+ max_tokens : config . openrouter . maxTokens ,
143+ top_p : 0.9 ,
144+ plugins : [ { id : 'file-parser' , pdf : { engine : this . pdfEngine } } ] ,
145+ } ;
146+ const finalResponse = await this . _makeChatAPIRequest ( finalRequest ) ;
133147 responseMessage = finalResponse . choices [ 0 ] . message ;
148+
149+ } else {
150+ // Original path: No search, just get the formatted JSON directly
151+ const noSearchRequest = {
152+ model : this . model ,
153+ messages : messages ,
154+ response_format : openRouterMCQSchema ,
155+ temperature : config . openrouter . temperature ,
156+ max_tokens : config . openrouter . maxTokens ,
157+ top_p : 0.9 ,
158+ plugins : [ { id : 'file-parser' , pdf : { engine : this . pdfEngine } } ] ,
159+ tool_choice : "none" ,
160+ } ;
161+ const response = await this . _makeChatAPIRequest ( noSearchRequest ) ;
162+ responseMessage = response . choices [ 0 ] . message ;
134163 }
135164
136165 const parsedContent = this . _parseAndValidateResponse ( responseMessage . content ) ;
@@ -139,10 +168,7 @@ class OpenRouterService {
139168 throw new Error ( 'Invalid response format from OpenRouter' ) ;
140169 }
141170
142- // Calculate total size of all PDFs
143171 const totalSize = pdfBuffers . reduce ( ( sum , buffer ) => sum + buffer . length , 0 ) ;
144-
145- // Validate and enhance the quiz
146172 const quiz = this . validateAndEnhanceQuiz ( parsedContent . quiz , totalSize , pdfBuffers . length ) ;
147173
148174 logger . info ( `Successfully generated ${ quiz . questions . length } MCQs from ${ pdfBuffers . length } PDF(s)` ) ;
0 commit comments