diff --git a/src/app/api/ai-event/route.ts b/src/app/api/ai-event/route.ts index b80c394..26b174b 100644 --- a/src/app/api/ai-event/route.ts +++ b/src/app/api/ai-event/route.ts @@ -1,16 +1,17 @@ import { NextResponse } from "next/server"; import { auth } from "@/auth"; import { headers } from "next/headers"; +import { openRouterClient } from "@/lib/openrouter-client"; export async function POST(request: Request) { const session = await auth.api.getSession({ headers: await headers(), }); - + if (!session?.user) { return NextResponse.json( { error: "Authentication required" }, - { status: 401 } + { status: 401 }, ); } @@ -20,13 +21,13 @@ export async function POST(request: Request) { if (!prompt || typeof prompt !== "string" || prompt.trim().length === 0) { return NextResponse.json( { error: "Prompt is required and must be a non-empty string" }, - { status: 400 } + { status: 400 }, ); } if (prompt.length > 2000) { return NextResponse.json( { error: "Prompt must be less than 2000 characters" }, - { status: 400 } + { status: 400 }, ); } @@ -57,29 +58,23 @@ Rules: - Output ONLY valid JSON (no prose). `; - const res = await fetch("https://openrouter.ai/api/v1/chat/completions", { - method: "POST", - headers: { - Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - model: "openai/gpt-4.1-nano", - messages: [ - { role: "system", content: systemPrompt }, - { role: "user", content: prompt }, - ], - }), - }); - - const data = await res.json(); try { - const content = data.choices[0].message.content; - const parsed = JSON.parse(content); + const result = openRouterClient.callModel({ + model: "openai/gpt-5.4-mini", + instructions: systemPrompt, + input: prompt, + }); + + const text = await result.getText(); + const parsed = JSON.parse(text); return NextResponse.json(parsed); - } catch { + } catch (error) { + console.error("AI Event Creation Error:", error); return NextResponse.json( - { error: "Failed to parse AI output", raw: data }, + { + error: "Failed to parse AI output", + raw: error instanceof Error ? error.message : error, + }, { status: 500 }, ); } diff --git a/src/app/api/ai-summary/route.ts b/src/app/api/ai-summary/route.ts index 6268532..6f63e7c 100644 --- a/src/app/api/ai-summary/route.ts +++ b/src/app/api/ai-summary/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from "next/server"; import { auth } from "@/auth"; import { headers } from "next/headers"; +import { openRouterClient } from "@/lib/openrouter-client"; export async function POST(request: Request) { const session = await auth.api.getSession({ @@ -30,32 +31,18 @@ export async function POST(request: Request) { ); } - const res = await fetch("https://openrouter.ai/api/v1/chat/completions", { - method: "POST", - headers: { - Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`, // Server-side only - "Content-Type": "application/json", - }, - body: JSON.stringify({ - model: "@preset/i-cal-editor-summarize", // FREE model - messages: [ - { - role: "system", - content: `You summarize a list of events in natural language. Include date, time, and title. Be concise.`, - }, - { role: "user", content: JSON.stringify(events) }, - ], - temperature: 0.4, - // max_tokens: 300, - }), + const result = openRouterClient.callModel({ + model: "@preset/i-cal-editor-summarize", // FREE model + instructions: + "You summarize a list of events in natural language. Include date, time, and title. Be concise.", + input: JSON.stringify(events), + temperature: 0.4, }); - const data = await res.json(); - const summary = - data?.choices?.[0]?.message?.content || "No summary generated."; + const summary = await result.getText(); return NextResponse.json({ summary }); } catch (error) { - console.error(error); + console.error("AI Summary Error:", error); return NextResponse.json( { error: "Failed to summarize events" }, { status: 500 },