feat: enhance OpenAI provider with web research context
This commit is contained in:
@@ -5,6 +5,7 @@ import type {
|
||||
DimensionResult,
|
||||
ItemResearch,
|
||||
} from "../types";
|
||||
import type { SearchResult } from "./tavily";
|
||||
|
||||
const client = new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY,
|
||||
@@ -140,3 +141,75 @@ Provide a comprehensive comparison with scores, pros/cons, and a recommendation.
|
||||
`Failed to generate comparison after ${MAX_RETRIES} attempts: ${lastError?.message}`
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateComparisonWithResearch(
|
||||
request: ComparisonRequest,
|
||||
searchResults: Record<string, SearchResult[]>
|
||||
): Promise<ComparisonResult> {
|
||||
const allResults = Object.values(searchResults).flat();
|
||||
if (allResults.length === 0) {
|
||||
return generateComparison(request);
|
||||
}
|
||||
|
||||
let researchContext = "Web research data:\n\n";
|
||||
for (const [itemName, results] of Object.entries(searchResults)) {
|
||||
if (results.length === 0) continue;
|
||||
researchContext += `=== ${itemName} ===\n`;
|
||||
for (const r of results) {
|
||||
researchContext += `- ${r.title}: ${r.content}\n Source: ${r.url}\n`;
|
||||
}
|
||||
researchContext += "\n";
|
||||
}
|
||||
|
||||
const userPrompt = `Compare the following items: ${request.items.join(", ")}
|
||||
${request.query ? `Focus: ${request.query}` : ""}
|
||||
${request.dimensions?.length ? `Specific dimensions to include: ${request.dimensions.join(", ")}` : ""}
|
||||
|
||||
${researchContext}
|
||||
|
||||
Use the web research data above to provide factual, data-driven insights. Reference specific data points in your analysis. Provide a comprehensive comparison with scores, pros/cons, and a recommendation.`;
|
||||
|
||||
let lastError: Error | null = null;
|
||||
|
||||
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
||||
try {
|
||||
const response = await client.chat.completions.create({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [
|
||||
{ role: "system", content: SYSTEM_PROMPT },
|
||||
{
|
||||
role: "system",
|
||||
content:
|
||||
"You have access to real web search results. Use them to ground your comparison in factual data. Cite specific findings from the research when scoring and analyzing items.",
|
||||
},
|
||||
{ role: "user", content: userPrompt },
|
||||
],
|
||||
response_format: { type: "json_object" },
|
||||
temperature: 0.3,
|
||||
});
|
||||
|
||||
const content = response.choices[0]?.message?.content;
|
||||
if (!content) {
|
||||
throw new Error("Empty response from OpenAI");
|
||||
}
|
||||
|
||||
const parsed: unknown = JSON.parse(content);
|
||||
|
||||
if (!validateComparisonResult(parsed)) {
|
||||
throw new Error("Invalid comparison result structure from OpenAI");
|
||||
}
|
||||
|
||||
return parsed;
|
||||
} catch (error) {
|
||||
lastError = error instanceof Error ? error : new Error(String(error));
|
||||
|
||||
if (attempt < MAX_RETRIES) {
|
||||
await sleep(RETRY_DELAY_MS * attempt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Failed to generate comparison with research after ${MAX_RETRIES} attempts: ${lastError?.message}`
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user