mirror of
https://github.com/vercel-labs/json-render.git
synced 2026-09-14 13:41:32 +08:00
4bb1151b6c
* add examples * live demos * og's * r3f mobile * rate limits * fix lint
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { streamText } from "ai";
|
|
import { gateway } from "@ai-sdk/gateway";
|
|
import { buildUserPrompt, type Spec } from "@json-render/core";
|
|
import { pdfCatalog } from "@/lib/catalog";
|
|
import { minuteRateLimit, dailyRateLimit } from "@/lib/rate-limit";
|
|
import { headers } from "next/headers";
|
|
|
|
export const maxDuration = 60;
|
|
|
|
const SYSTEM_PROMPT = pdfCatalog.prompt();
|
|
|
|
const DEFAULT_MODEL = "anthropic/claude-haiku-4.5";
|
|
|
|
export async function POST(req: Request) {
|
|
const headersList = await headers();
|
|
const ip = headersList.get("x-forwarded-for")?.split(",")[0] ?? "anonymous";
|
|
|
|
const [minuteResult, dailyResult] = await Promise.all([
|
|
minuteRateLimit.limit(ip),
|
|
dailyRateLimit.limit(ip),
|
|
]);
|
|
|
|
if (!minuteResult.success || !dailyResult.success) {
|
|
const isMinuteLimit = !minuteResult.success;
|
|
return new Response(
|
|
JSON.stringify({
|
|
error: "Rate limit exceeded",
|
|
message: isMinuteLimit
|
|
? "Too many requests. Please wait a moment before trying again."
|
|
: "Daily limit reached. Please try again tomorrow.",
|
|
}),
|
|
{
|
|
status: 429,
|
|
headers: { "Content-Type": "application/json" },
|
|
},
|
|
);
|
|
}
|
|
|
|
const { prompt, startingSpec } = (await req.json()) as {
|
|
prompt: string;
|
|
startingSpec?: Spec | null;
|
|
};
|
|
|
|
if (!prompt || typeof prompt !== "string") {
|
|
return Response.json({ error: "prompt is required" }, { status: 400 });
|
|
}
|
|
|
|
const userPrompt = buildUserPrompt({
|
|
prompt,
|
|
currentSpec: startingSpec,
|
|
});
|
|
|
|
const result = streamText({
|
|
model: gateway(process.env.AI_GATEWAY_MODEL ?? DEFAULT_MODEL),
|
|
system: SYSTEM_PROMPT,
|
|
prompt: userPrompt,
|
|
temperature: 0.7,
|
|
});
|
|
|
|
return result.toTextStreamResponse();
|
|
}
|