Skip to content

Commit 105f104

Browse files
committed
fix: tool calling priority so gemini could do it
1 parent ac85913 commit 105f104

1 file changed

Lines changed: 61 additions & 35 deletions

File tree

server/services/openrouter.js

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)