import { logOpenRouterCall } from './openRouterLogger.js'; function parseResponse(response) { if(!response?.usage?.cost) console.log(response); console.log('OpenRouter API call cost:', response?.usage); return { cost: response?.usage?.cost, prompt_tokens: response?.usage?.prompt_tokens, completion_tokens: response?.usage?.completion_tokens, data: JSON.parse(response.choices[0].message.content) }; } export async function summarizeSources({ openrouter, text, question }) { const prompt = ` You are a search result analyst. Based on the following search results for the query "${question}", provide a list of relevant sources with their full weblink with a concise summary for each source. `; const params = { model: 'openai/gpt-oss-120b:nitro', messages: [ { role: 'system', content: prompt }, { role: 'user', content: text }, ], reasoning: { effort: 'low' }, response_format: { type: 'json_schema', json_schema: { name: 'search_summaries', strict: true, schema: { type: 'object', required: ['sources'], additionalProperties: false, properties: { sources: { type: 'array', items: { type: 'object', required: ['url', 'summary'], additionalProperties: false, properties: { url: { type: 'string', description: 'Full URL of the source' }, summary: { type: 'string', description: 'Concise summary of the content' }, }, }, }, }, }, }, }, stream: false, }; // Using direct fetch API instead of OpenRouter SDK const apiKey = process.env.OPENROUTER_API_KEY; const fetchResponse = await fetch('https://openrouter.ai/api/v1/chat/completions', { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify(params), }); const response = await fetchResponse.json(); await logOpenRouterCall('summarizeSources', text, params, response); return parseResponse(response); } export async function rephraseQuestion({ question, previousClarification, originalQuestion }) { if(previousClarification) { const prompt = ` You are a search query expert. You are given a question and you return a search query for a web search engine that would return the best results to answer the question. Do NOT restrict the query using site: operator. Also give a list of 2 supplementary search queries to deepen the search. Today is the date of ${new Date().toLocaleDateString()}. The user has provided this clarification "${previousClarification}" to the original question: ` + originalQuestion; const params = { model: 'openai/gpt-5.4-mini', messages: [ { role: 'system', content: prompt }, { role: 'user', content: question }, ], reasoning: { effort: 'none' }, stream: false, response_format: { type: 'json_schema', json_schema: { name: 'queries', strict: true, schema: { required: [ 'query', 'supplementaryQueries'], type: 'object', additionalProperties: false, properties: { query: { type: 'string' }, supplementaryQueries: { type: 'array', items: { type: 'string' } }, } } } } }; const apiKey = process.env.OPENROUTER_API_KEY; const fetchResponse = await fetch('https://openrouter.ai/api/v1/chat/completions', { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify(params), }); const response = await fetchResponse.json(); await logOpenRouterCall('rephraseQuestion', question,params, response); return parseResponse(response); } const prompt = ` You are a search query expert. You are given a question and you return a search query for a web search engine that would return the best results to answer the question. Do NOT restrict the query using site: operator. Also give a list of 2 supplementary search queries to deepen the search. Today is the date of ${new Date().toLocaleDateString()}. The user cannot ask questions that a web search engine cannot answer. Like "Who are you". If the question is ambiguous or unsuited for a web search, you can ask for clarification. ${previousClarification ? `The user has provided this clarification to the original question: "${previousClarification}". Use this clarification to refine the search query.` : ''} `; const params = { model: 'openai/gpt-5.4-mini', messages: [ { role: 'system', content: prompt }, { role: 'user', content: question }, ], reasoning: { effort: 'none' }, stream: false, response_format: { type: 'json_schema', json_schema: { name: 'queries', strict: true, schema: { required: ['needsClarification', 'clarification', 'query', 'supplementaryQueries'], type: 'object', additionalProperties: false, properties: { needsClarification: { type: 'boolean', description: 'Indicates if the question is ambiguous and needs clarification' }, clarification: { type: 'string', description: 'If needsClarification is true, this field contains the clarification question to ask the user. Otherwise, it is an empty string.' }, query: { type: 'string' }, supplementaryQueries: { type: 'array', items: { type: 'string' } }, } } } } }; const apiKey = process.env.OPENROUTER_API_KEY; const fetchResponse = await fetch('https://openrouter.ai/api/v1/chat/completions', { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify(params), }); const response = await fetchResponse.json(); await logOpenRouterCall('rephraseQuestion', question,params, response); return parseResponse(response); } export async function summarizeFinalAnswer({ openrouter, text, question }) { const prompt = ` You are a search result analyst. Today is the date of ${new Date().toLocaleDateString()}. Based on the following search results for the query "${question}", Summarize the search results to answer the original query. Use Emoji and HTML. Tags allowed: , , ,
, 
    ,
  • , ,


    Also provide the most relevant sources. Answer in the language of the question. You may suggest followup searched to the user. `; const params = { model: 'openai/gpt-oss-120b:nitro', messages: [ { role: 'system', content: prompt }, { role: 'user', content: text }, ], reasoning: { effort: 'low' }, response_format: { type: 'json_schema', json_schema: { name: 'response', strict: true, schema: { type: 'object', required: ['fullAnswerHTMLSnippet', 'mostRelevantSources', 'suggestedSearches'], properties: { fullAnswerHTMLSnippet: { type: 'string' }, mostRelevantSources: { type: 'array', items: { type: 'string' } }, suggestedSearches: { type: 'array', items: { type: 'string' } }, }, }, }, }, stream: false, }; // Using direct fetch API instead of OpenRouter SDK const apiKey = process.env.OPENROUTER_API_KEY; const fetchResponse = await fetch('https://openrouter.ai/api/v1/chat/completions', { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify(params), }); const response = await fetchResponse.json(); await logOpenRouterCall('summarizeFinalAnswer', text, params, response); return parseResponse(response); }