adding web search to all recs

This commit is contained in:
2026-03-26 20:13:31 -03:00
parent f9f3d95406
commit 6fdfc3797a
7 changed files with 86 additions and 109 deletions

View File

@@ -1,5 +1,15 @@
import { openai } from '../agent.js';
import type { InterpreterOutput, RankingOutput, CuratorOutput } from '../types/agents.js';
import { z } from 'zod';
import { zodTextFormat } from 'openai/helpers/zod';
const CuratorSchema = z.object({
shows: z.array(z.object({
title: z.string(),
explanation: z.string(),
category: z.enum(["Definitely Like", "Might Like", "Questionable", "Will Not Like"])
}))
});
export async function runCurator(
ranking: RankingOutput,
@@ -18,36 +28,22 @@ export async function runCurator(
.map((s) => `- "${s.title}" (${s.category})`)
.join('\n');
const response = await openai.chat.completions.create({
model: 'gpt-5.4-mini',
const response = await openai.responses.parse({
model: 'gpt-5.4',
temperature: 0.5,
service_tier: 'flex',
response_format: { type: 'json_object' },
messages: [
{
role: 'system',
content: `You are a TV show recommendation curator. For each show, write a concise 1-2 sentence explanation of why it was assigned to its category based on the user's preferences.
Your output MUST be valid JSON:
{
"shows": [
{
"title": string,
"explanation": string,
"category": "Definitely Like" | "Might Like" | "Questionable" | "Will Not Like"
}
]
}
tools: [
{ type: 'web_search' }
],
text: { format: zodTextFormat(CuratorSchema, "shows") },
instructions: `You are a TV show recommendation curator. For each show, write a concise 1-2 sentence explanation of why it was assigned to its category based on the user's preferences.
Rules:
- Preserve the exact title and category as given
- Keep explanations concise (1-2 sentences max)
- Reference specific user preferences in the explanation
- Be honest — explain why "Questionable" or "Will Not Like" shows got that rating`,
},
{
role: 'user',
content: `User preferences summary:
input: `User preferences summary:
Liked: ${JSON.stringify(interpreter.liked)}
Themes: ${JSON.stringify(interpreter.themes)}
Tone: ${JSON.stringify(interpreter.tone)}
@@ -56,11 +52,7 @@ Avoid: ${JSON.stringify(interpreter.avoid)}
Shows to describe:
${showList}`,
},
],
});
const content = response.choices[0]?.message?.content ?? '{"shows":[]}';
const result = JSON.parse(content) as { shows: CuratorOutput[] };
return result.shows ?? [];
return response.output_parsed?.shows ?? [];
}