From f55e6e2f60357faea19f9ae262f1eaf4998c2296 Mon Sep 17 00:00:00 2001 From: Lautaro Paskevicius Date: Fri, 2 Oct 2026 16:09:52 -0300 Subject: [PATCH] fix(ai): log roast-me stream failures and pass system prompts via `system` roast-me's streamObject had no onError, so model and schema failures never reached the logs. Grade, take-home and roast-me put the system prompt in `messages`, which triggered the AI SDK prompt-injection warning on every request (~98% of open-silver WARN logs in Dash0). Co-Authored-By: Claude Opus 5.5 --- src/app/roast-me/api/analyze/route.ts | 11 ++++------- src/pages/api/grade.ts | 4 +++- src/resume-checker/prompts/grade.ts | 11 ++--------- src/takehome-checker/index.ts | 6 ++---- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/app/roast-me/api/analyze/route.ts b/src/app/roast-me/api/analyze/route.ts index 9cda266..6bcb7cb 100644 --- a/src/app/roast-me/api/analyze/route.ts +++ b/src/app/roast-me/api/analyze/route.ts @@ -29,13 +29,10 @@ export async function POST(req: NextRequest) { strictJsonSchema: true, }, }, - messages: [ - { - role: "system", - content: isUnhinged ? SYSTEM_PROMPT_UNHINGED : SYSTEM_PROMPT, - }, - { role: "user", content: [{ type: "image", image: snapshot }] }, - ], + system: isUnhinged ? SYSTEM_PROMPT_UNHINGED : SYSTEM_PROMPT, + messages: [{ role: "user", content: [{ type: "image", image: snapshot }] }], + onError: ({ error }) => + console.error("[roast-me/analyze] stream failed", error), }); return result.toTextStreamResponse(); diff --git a/src/pages/api/grade.ts b/src/pages/api/grade.ts index 1915ebb..8cde8f1 100644 --- a/src/pages/api/grade.ts +++ b/src/pages/api/grade.ts @@ -5,6 +5,7 @@ import { } from "@/resume-checker/fetch-resume"; import { exampleResponses, + getSysPrompt, messages, ResponseData, ResponseSchema, @@ -76,7 +77,8 @@ export default async function handler( const completion = await generateObject({ model: "google/gemini-2.5-flash", temperature: 0, - messages: messages(parsed, pdfBuffer), + system: getSysPrompt(parsed?.info?.Author), + messages: messages(pdfBuffer), schema: ResponseSchema, }); diff --git a/src/resume-checker/prompts/grade.ts b/src/resume-checker/prompts/grade.ts index 5d6fe46..a8f4b2a 100644 --- a/src/resume-checker/prompts/grade.ts +++ b/src/resume-checker/prompts/grade.ts @@ -157,10 +157,7 @@ function createInput(data: Buffer): ModelMessage { } /* Moving the fs.readFileSync call deeper causes an error when reading files */ -export function messages( - parsed: { text: string; info?: any }, - pdfBuffer: Buffer, -): ModelMessage[] { +export function messages(pdfBuffer: Buffer): ModelMessage[] { const trainMessages: ModelMessage[] = [ { data: fs.readFileSync(path.join(process.cwd(), "public/s_resume.pdf")), @@ -183,11 +180,7 @@ export function messages( createAssistantResponse(response), ]); - return [ - { role: "system", content: getSysPrompt(parsed?.info?.Author) }, - ...trainMessages, - createInput(pdfBuffer), - ]; + return [...trainMessages, createInput(pdfBuffer)]; } function hasGmail(flag: string) { diff --git a/src/takehome-checker/index.ts b/src/takehome-checker/index.ts index 37b5889..b63143f 100644 --- a/src/takehome-checker/index.ts +++ b/src/takehome-checker/index.ts @@ -17,10 +17,8 @@ export async function analyzeTakeHome( const { text } = await generateText({ model: openai("gpt-4o-mini"), - messages: [ - { role: "system", content: prompt }, - { role: "user", content }, - ], + system: prompt, + messages: [{ role: "user", content }], maxOutputTokens: 10000, temperature: 0, });